前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mobx 入门

mobx 入门

作者头像
copy_left
发布2019-08-21 16:30:27
1K0
发布2019-08-21 16:30:27
举报
文章被收录于专栏:方球

mobx

响应式状态管理库

安装

代码语言:javascript
复制
// npm
npm i --save mobx

// yarn
yarn add mobx

基础概念

  • 所谓的响应式,既是将原有数据结构,例如 数组,对象等转变为可观察对象, 通过对可观察对象的监控,当数据变化做出对应的动作,所以可以大概归纳为:
    • 构建观察对象
    • 设置响应动作
  • 在mobx中构建观察对象存在两种模式
    • 函数模式
    • 装饰器模式(针对类定义)

函数模式

创建观察对象
代码语言:javascript
复制
// 引入mobx
import { observable } from 'mobx'

// 对象转换
const obj = observable({
    name: 'Rogan',
    age: 24
})

// 数组转换
const arr = observable([
    1, 2, 3
])

// map 转换
const map = observable(new Map([ ["name", "Rogan"] ]))


/*
    注意:
        我们实际操作的是观察对象,而非我们创建时传入的值,
        我们可能修改保存观察对象的变量,这是将丢失观察对象.
        
        例如: let arr = observable([1)
                arr = [2]
        
*/
响应变化

当函数内的观察对象属性值变化时,将触发该函数, 默认初始调用一次

代码语言:javascript
复制
    const obj = observable({
        name: 'Rogan',
        age: 24 
    })
    
    autorun(() => {
        console.log(obj.name)
    })
    // 默认调用
    // -> Rogan 
    
    obj.name = 'coco'
    // 触发 autorun 
    // -> coco
    
    obj.age = 24
    // 不会触发 autorun
    
    obj.name = 'coco'
    // 赋值相同时,不会触发 autorun

有时我们需要观察对象处理后的数据, 当观察对象值变化后,产生新的值

响应规则与 autorun 类似, 只对函数内的值作响应

代码语言:javascript
复制
computed(get, set)
// get: 获取值函数
// set: 设置值函数
代码语言:javascript
复制
import { observable, computed } from 'mobx' 

const obj = observable({
    name: 'Rogan',
    age: 24
})

// 取值对象
const userName = computed(() => {  
return `username: ${obj.name} `})

// 获取computed 值
console.log(userName.get()) // -> username: Rogan

// 响应 name 变化
userName.name = "Coco" 
console.log(userName.get()) // -> username: Coco 


// 取值, 设值对象
const userAge = computed(

    // 取值方法
    () => return obj.name,
    
    // 设值方法
    data => console.log(data)

)

console.log(userAge.get()) // -> 24
userAge.set(30) // -> 30

指定响应值

代码语言:javascript
复制
reaction( watchFn, actionFn )

// watchFn: 监控函数, 返回被监控数据.
// actionFn: 响应函数, 接收 watchFn 返回的响应数据
代码语言:javascript
复制
const Rogan = observable({
    id: "123",
    name: "Rogan",
    age: 24
})


// 监控 name age 数据
reaction(() => [Rogan.name, Rogan.age], data => console.log(data) )

// 响应 name age 变化

Rogan.name = "Coco"
// -> [ Coco, 24 ]

Rogan.age = 30
// -> [ Coco, 30 ]

// 不响应 id
Rogan.id = "111"

筛选响应

某些时候,我们希望存在多个观察值的情况下,只对其中的某些值做或某些情况响应.

代码语言:javascript
复制
when(filteFn, actionFn)

// filteFn 过虑函数, 返回 boolean

// actionFn 响应函数,当 filteFn 返回 true 时执行, 只执行一次
代码语言:javascript
复制
const Rogan = observable({
    name: 'Rogan',
    age: 100
})

// when 将返回终止函数,调用终止函数后,when的响应函数将不会执行
let dispose =  when(() => Rogan.age === 110, () => console.log("dead"))

//终止响应函数
// dispose()

// 触发响应
Rogan.age = 110 // -> dead

// 响应函数只会执行一次
Rogan.age = 0
Rogan.age = 110 // 无输出
  • when promise模式 当when 未配置响应函数时, 将返回Promise
代码语言:javascript
复制
let pm =  when(() => Rogan.age === 110)

pm.then(

    () => console.log('dead'),
    () => console.log('live')

)

状态修改函数

将多个状态修改,合并为一次提交给 autorun

代码语言:javascript
复制
const rogan = observable({

    id: '123',
    name: 'Rogan',
    age: 24,
    
})

autorun(() => {
    console.log(rogan.name, rogan.age)
})


// 普通状态修改函数
let change = (name, age) => {
    rogan.name = name
    rogan.age = age
}

// 合并后的修改函数
let warpChange =  action('age', (name, age) => {
    rogan.name = name
    rogan.age = age
})


change('coco', 30)
// 触发多次 autorun
// -> coco 24
// -> coco 30


warpChange('jeck', 11)
// 只触发一次 autorun
// -> jeck 11

装饰器模式

多数情况下,mobx 配置和 react 使用在类中

类中使用 observable
代码语言:javascript
复制
class Man {

    // 使用装饰器 构建装饰器值
    @observable name = ''
    @observable age = 0
    
    // 普通属性
    id = '0000'
    
    constructor(name, age){
        this.name = name
        this.age = age

        // log
        autorun( () => console.log(`update: ${this.name} ${this.age} ${this.id}`))
    }
    
}


const Rogan = new Man('Rogan', 100)

Rogan.name = "Wolf" // -> Wolf 100 0000
Rogan.id = "0001" // 无响应
Rogan.age = 101 // -> Wolf 101 0001
类中使用 action
代码语言:javascript
复制
class Man {

    // 使用装饰器 构建装饰器值
    @observable name = ''
    @observable age = 0
    
    // 普通属性
    id = '0000'
    
    constructor(name, age){
        this.name = name
        this.age = age

        // log
        autorun( () => console.log(`update: ${this.name} ${this.age} ${this.id}`))
    }
    
    // 使用 .bound 将函数绑定在对象上
    // 类似 this.changeName.bind(this)
    @action.bound
    changeName(name){
        this.name = name
    }
    
    // 普通方法
    changeAge(age){
        this.age = age
    }
    
}



const changeName = Rogan.changeName
changeName('Body') // -> Body 101 0001

const changeAge = Rogan.changeAge
changeAge() // 报错 TypeError: Cannot set property 'name' of undefined
类中使用 computed
代码语言:javascript
复制
class Add {

    @observable a = 0
    @observable b = 0

    @computed get total (){
        return this.a + this.b
    }
    // 这里 set 将自动挂载 不需要添加装饰器
    set total(data) {
        console.log("Cannot set total value")
    }
    

    constructor(a, b){
        this.a = a
        this.b = b
    }
    
}


const add = new Add(10, 12)
console.log(add.total) // -> 22
add.total = 100 // -> Cannot set total value

action 在绑定异步函数中,外层action 对异步内的回调时无效的

代码语言:javascript
复制
class 
React
  • 安装 mobx-react 依赖
代码语言:javascript
复制
// npm 
npm i --save mobx-react

//yarn

yarn add mobx-react
代码语言:javascript
复制
import { observable, autorun, computed, action, when, reaction } from 'mobx'
import { observer } from 'mobx-react'
import "./index.less"

// @oberver 将组件内的 rander 函数, 通过 autorun做监听
export default @observer class Cmp extends React.Component{
    
    @observable count = 0
    
    @action.bound
    add(){
        this.count += 1;
    }
    
    render(){
        
        return (
            
            <div>
                
                <div>
                    {this.count}
                </div>
                
                <button onClick={this.add}>
                    add
                </button>
            </div>
            
        )
        
    }
    
    
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.02.27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • mobx
    • 安装
      • 基础概念
        • 函数模式
          • 装饰器模式
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档