最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • mobx常用方法梳理

    正文概述 掘金(伊水河)   2020-11-26   685

    使用react刚好一年,一直是用的mobx进行状态管理。前一段时间在使用mobx过程中突然发现最近所使用的方式都是有一定问题的,故重新梳理其使用方式。

    mobx主要是创建响应式数据,然后当数据变化时通过一些方式来做出相应的处理,常用的方法有:

    • observable
    • toJS
    • computed
    • action

    下面我们来一一介绍

    observable

    将一个对象变为可观察对象,用法比较简单:

    import { observable } from 'mobx'
    
    class Store{
    
        @observable
        obj={a:1}
    
        @observable
        num=1
    
    }
    

    经过observable装饰过的属性即可成为响应式数据,供之后使用。

    toJS

    将通过observable转换过的数据转回普通的js对象。以上面代码为前提,假设它导出了export default new Store(),那么在使用的地方通常可以这么写:

    import { toJS } from 'mobx'
    import store from './store'
    
    const jsObj=toJS(store)
    
    

    jsObj已是普通的js对象,可在其他地方使用。

    computed

    根据现有可观察值生成一个新的值(类比vue的计算属性或vuex的getter)。用法:

    import { observable, computed } from 'mobx'
    
    class Store{
        @observable n=1
    
        @computed get nPlus1(){
            return this.n+1
        }
    }
    

    以上代码中的nPlus1n变化时会重新计算,保持始终比n大1。那么怎么来改变n呢?那就要有请action了。

    action

    用来修改可观察数据,仅限同步。(是否想到了vuex的mutation)

    import { observable, action } from 'mobx'
    
    class Store{
        @observable order=1
    
        @action setOrder(val){
            this.order=val
        }
    }
    

    不建议直接更改order的值,在需要的地方通过调用setOrder来修改。

    异步修改状态

    那么异步呢?实际开发中需要通过接口获取值来修改页面状态可是家常便饭。可通过以下几种方式来进行异步状态修改:

    在需要修改状态的地方调用已有action

    import { observable, action } from 'mobx'
    
    class Store{
        @observable order=1
        @observable order2=1
    
        @action setOrder(val){
            this.order=val
        }
    
        @action setOrder2(val){
            this.order2=val
        }
    
        async af(){
            const {no,no2}=await asyncFunc()
            this.setOrder(no)
            this.setOrder2(no2)
        }
    }
    

    上栗使用async functionpromise在需要修改状态的地方调用已有action即可。

    至此,已经可以很好的使用mobx了。使用react的话,配合mobx-react的observer便可解决大部分问题。如果想要了解更多的话,继续往下看吧。

    runInAction

    runInAction可以避免我们去定义很多的action来修改数据。数据的修改可以放心的用之包裹起来,修改上栗:

    import { observable, runInAction } from 'mobx'
    
    class Store{
        @observable order=1
        @observable order2=1
    
        async af(){
            const {no,no2}=await asyncFunc()
            runInAction(()=>{
                this.order=no
                this.order2=no2
            })
        }
    }
    

    可以看到代码简洁了许多。

    flow

    flow接收一个generator,代码也非常简洁,同时也更好阅读,官方推荐。来看下写法,修改上面代码:

    import { observable, flow } from 'mobx'
    
    class Store{
        @observable order=1
        @observable order2=1
    
        doSth=flow(function * (){
            const {no,no2}=yeild asyncFunc()
            this.order=no
            this.order2=no2
        })
    }
    

    在需要的地方调用doSth即可

    响应数据变化

    到此为止已经可以定义和修改数据了,但是否少了些什么。数据变化后我们总要处理点什么吧,比如更新视图(没错,watch没跑了)。那就有请下面几位小伙伴啦。

    autorun

    监测传入函数参数中用到的可观察数据:

    import { observable, action, autorun } from 'mobx'
    
    class Store{
        @observable order=1
    }
    
    const store=new Store()
    
    autorun(() => console.log(store.order));
    

    上面代码当order变化时,便会触发传入autorun的函数,打印出新的order。因为autorun的函数入参中用到了order(store.order)。

    when

    有条件的监测,接收两个参数均为函数,第一个函数返回true时便会执行第二个函数

    when(()=>someCondition,()=>{ /**doSth*/ })

    reaction

    可以自定义需要监测哪些字段,同样接受两个参数,第一个参数返回需要监测的字段,当其变化时便会执行第二个函数

    import { observable, reaction } from 'mobx'
    
    class Store{
        @observable order=1
        @observable order2=2
    }
    
    const store=new Store()
    
    reaction(()=>store.order,order => console.log(order));
    

    上栗中只有order变化时才会打印,而order2则不被监测。在某些地方使用也很方便,比如将分页数据的页码作为第一个参数的返回值,从而在第二个函数中做翻页请求(别瞅hook)。

    另外,这几个响应函数

    • 会返回一个取消监测的函数const disposer = autorun(()=>{}),调用disposer()之后便可取消监测。可在组件销毁时使用。
    • 比本文多一个入参,可配置响应函数的行为,位置在最后。

    起源地下载网 » mobx常用方法梳理

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元