mobx基本概念介绍

安装遇到的问题:

Mbox的装饰器语法为es7语法。所以需要提供babel支持。

1 需要安装transform-decorators-legacy。

  Npm install babel-plugin-transform-decorators –save-dev

  Npm install babel-preset- stage-1

  Npm install babel-preset- es2015

 

2 需要在根目录下新建一个.babelrc文件。

  

{

  "presets": ["es2015", "stage-1","react"]

"plugins": ["transform-decorators-legacy"]

}

 

安装教程https://github.com/wulibaibao/react-mobx-demo

利用官方推荐的第二种办法:Rewire create-react-app to use MobX

 

1 基本介绍

  mobx   ------该模块通过提供诸如obersevable,autorun等基础函数和语法实现数据的可监控和自动执行

  常用的函数:

 -----------------

 Obersevable: 让数据可监控。类似vue中的state。用来控制数据

  Action:数据响应。类似vue中的mutaion ,派发动作。实现数据的操作

  Comuted:数据的筛选。类似vue中的getters。

 

 

  mobx-react :连接react组件和mbox中store数据的桥梁。

 

常见api:

 Oberser  --à让某个组件成为观察者。

 

  注意1 单独组件如果要引用store中的数据。需要通过@inject(store)

 

 

import { observable, computed } from "mobx";

import {Provider}from "mobx-react";

 

class Store{

  @observable

   todo=[{title:"初始标题",done:false},{title:"标题2",done:true}];

   @observable count=0;

const store=new Store()

}

const store=new Store()

<Provider store={store}>

    <App />

</Provider>

 

 

 

组件中

 

@inject("store")  =è注意只接受store

@observer class App extends Component{

render(){

let count=this,props. store.count;

  return(<div>{count}</div>)

}

}

 

      2注意@action中函数的this指向问题。

class Store{

@action changeTitle=({index,title})=>{

      console.log(title)

      this.todo[index].title=title;  这里this指向是Store对象,箭头函数,锁定this对象

      console.log(toJS(this.todo))

     }

 

@action changeTitle({index,title}){

      console.log(title)

      this.todo[index].title=title;  这里this指向是单击时的dom对象

      console.log(toJS(this.todo))

     }

}

 

 

 

 

组件中:

@observer class App extends Component{

render(){

        let {count,add,todo,changeTitle}=this.props.store

 }

    <input type="button" value="修改" onClick={()=>{  changeTitle({index:0,title:"更新后的数据"})    }    }/>

}

 

 注意;启动mbox的严格模式。在mobx4版本中已经做了改动》

  4之前的版本

  import {observable,action,toJS,computed,runInAction,useStrct} from "mobx"

useStrct(true)

4以后的版本

import {observable,action,toJS,computed,runInAction, configure} from "mobx"

configure({enforceActions:true})

 

 

 Uncaught ReferenceError: regeneratorRuntime is not defined报错的问题:

  现象:

使用 ES7 的 async/await 时报错。

 

解决方法:

$ npm i --save-dev babel-plugin-transform-runtime

 

在 .babelrc 文件中添加:

"plugins": [[

    "transform-runtime",

    {

      "helpers": false,

      "polyfill": false,

      "regenerator": true,

      "moduleName": "babel-runtime"

    }

  ]]

 

最后.babelrc的配置:

{

  "presets": ["es2015", "stage-1","react"],

   "plugins": [

                   [

                       "transform-runtime",

                       {

                         "helpers": false,

                         "polyfill": false,

                         "regenerator": true,

                         "moduleName": "babel-runtime"

                       }

                     ],

 

                    "transform-decorators-legacy"

              ]

}

 

 

Mobx中异步action的几种方式:

(这里一定要注意写成箭头函数的形式)

1 通过async +await异步函数结合 runInAction函数

实例:

import {observable,action,toJS,computed,runInAction,configure} from "mobx"

configure({enforeceActions:true})

 

class Store{

@observable articleData=[];   ====》用来获取最后的数据

  @observable loading=false   =====》用来显示loading状态

  

 

  @action getArticleData=async()=>{  注意这里箭头函数的写法

     console.log("this:",this)

     this.loading=true

    console.log("异步。。。")

      let res= await getData()

      console.log("res:",res)

      runInAction(()=>{

          this.loading=false      

          this.articleData=res.data.data;

      })

  }

}

 

方式二:

类似redux,一个异步请求,走3个action分别代表异步请求开始。成功和错误三个状态。

这里唯一要注意的就是action必须使用箭头函数

Eg:

import {observable,action,toJS,computed,runInAction,configure,bound} from "mobx"

configure({enforeceActions:true})

class Store{

  @observable articleData=[];     ====》用来获取最后的数据

  @observable loading=false      =====》用来显示loading状态

 

  @action getArticleData=()=>{

this.loading=true;

    console.log("getData:",getData)

    getData().then(this.fetchSuccess).catch(this.fetchFail)

  }

@action.bound fetchSuccess=(res=>{

     console.log("res:",res)

     this.loading=false;

     this.articleData=res.data.data

  })

  @action.bound fetchFail=(err=>{

    console.log("err:",err)

  })

}

const getData=()=>{

   return axios.get(baseUrl+"/article/list?start=0&size=20")

}

 

 

 第三种:内联action的方式。

和第二种有点类似。第二种方式 fetchSuccess和fetchFail 分别抽离出来。而内联action则是直接写在一个action中。

Eg:

import {observable,action,toJS,computed,runInAction,configure,bound} from "mobx"

configure({enforeceActions:true})

 

@observable articleData=[];

@observable loading=false

 

@action getArticleData=()=>{

 

    this.loading=true;

    console.log("getData:",getData)

    getData().then(action('fetchSuccess',res=>{

 

      this.loading=false;

      this.articleData=res.data.data

    })).catch(action('fetchFail',err=>{

      console.log("err:",err)

    }))

 

  }

注意。这里action需要给加上名称。

 

错误日志:

Leading decorators must be attached to a class declaration

原因:

@inject("store");装饰器后面不能加分号。

错误写法:

@inject("store"); //注意这里的分号

@observer class AuthorizedRoute extends Component{

  render(){

    return(

               <div>

                       21231231

               </div>

        )

  }

}

正确写法:

@inject("store") //注意这里的分号

@observer class AuthorizedRoute extends Component{

  render(){

    return(

               <div>

                       21231231

               </div>

        )

  }

}

 

装饰器的写法规则 @装饰器1 @装饰器2 @装饰器3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值