mobx 中异步更新状态

异步更新方法1

需要用到runInAction用这个方法来提交异步更改

@observable users = []
@action.bound async getData () {
      const users = await axios.get('https://api.github.com/users')
      runInAction(() => this.users = users.data)
}

异步更新方法2

使用flow来实现异步更新状态,flow需要我们传入一个generator函数,这个函数的this指向也有问题,所以我们需要使用bind方法更改this指向

getData = flow(function* (){
    const users = yield axios.get('https://api.github.com/users')
    this.users = users.data
}).bind(this)

mobx数据监测

什么是数据监测?

  • 当某一数据发生变化的时候我们想根据这个值得到另一个值
  • 当某一数据发生变化的时候我们想去做另一件事情

computed计算值

  • 什么是计算值

计算值是可以根据现有的状态或其他计算值衍生出的值

  • 什么时候使用计算值

将复杂的业务逻辑从模板中抽离出来

数据监测第一种方式(computed,根据一个值派生出另一个值)

当计算值里包含的值变化的时候就会根据变化的值派生新的值,这个方法必须return一个值,要被computed来装饰

import { observable, action, computed } from 'mobx'
class BirdStore {
    @observable count = 10
    @observable price = 25

    @computed get totalPrice () {
        return this.count * this.price
    }
}

数据监测第二种方法(autorun,根据值变化执行一个方法)

当数据发生变化的时,你想根据状态产生“效果”,请使用 autorun 会在初始化的时候执行一次,会在发生变化的时候执行 , 要求我们传递一个函数这个函数里面用到的数据就是根据改变而产生效果的数据,第二个参数里面有个delay属性这个属性是延迟几秒后执行

// store中
import { observable,  action, configure, autorun } from 'mobx'
import axios from 'axios'

configure({ enforceActions: 'observed' })

class counterStore {
    @observable username = 'username'
    constructor(){
                // 数据改变执行方法      
        autorun(() => {
            try{
                unipueUsername(this.username)
                console.log('用户名可用')
            }catch (e){
                console.log(e.message)
            }
        }, { delay: 2000 })
    }

    @action.bound changeUsername = function (username) {
        this.username = username
    }
}

const counter = new counterStore()

function unipueUsername (username) {
    return new Promise ((resolve, reject) => {
        if(username === 'admin') {
            reject('用户名失败')
        }else{
            resolve()
        }
    })
}

export default counter

视图中

const { counter } = this.props
    return <div>
        <input value={counter.username} onChange={(e) => counter.changeUsername(e.target.value)}></input>
        {counter.username}
    </div>

禁止普通函数更改程序状态并引入action装饰器

因为类里面的函数都可以更改状态,这mobx是被允许的,通过配置强制让action函数来更改状态,开启了之后就只有action装饰器装饰过的函数才可以更改状态了

import { configure } from 'mobx'

configure({ enforceActions: 'observed' })