mobx 状态管理工具
cnpm i mobx mobx-react -S
与redux的区别:
- 仓库可以有多个
- 用的是面向对象的语法
注意:mobx用到了装饰器语法,所以需要先配置支持装饰器
原生监控数据: Object.defineProperty(es5)、observable和proxy(es6)
1.mobx-建立一个store示例
1.box&&map的store
修改直接是store.set('xx','xx')

2.class类store
@observable 变量名=值 可以监听数据的变化
@action 修改动作
@computed 类似计算属性
autorun 监听所有数据的变化 autorun(()=>{})
reaction 监听特定数据的变化 reaction(()=>[a,b….],()=>{ })
// store/index.jsimport {observable,autorun,reaction,action,computed} from 'mobx'class Store {// observable监听数据变化;@observable a=5;@observable b=21;// action修改@action changeA=()=>{//箭头函数,为了使用thisthis.a=999}@action getData= async()=>{//异步示例-一般在componentDidMount中使用fetch('url').then(res=>res.json()).then(res=>{this.list=res})}// 获取计算属性-不能用箭头函数@computed get getA(){return this.a + '经过计算属性包装/筛选'}}let s=new Store()//此时s就是实例化的仓库之一// autorun对observables做出响应,监听所有数据的变化autorun(()=>console.log('数据变化了'))s.a=100console.log(s.a)// 监听特定数据的变化(第一个参数回调返回一个数组,只监听数据内的数据变化)reaction(()=>[s.b],()=>console.log('b数据变化了'))// 导出仓库export default s// 此时,只能获取到第一次的值,仓库的数据其实修改了,但是页面并没响应(且需要组件内部引入仓库-得到或使用仓库的属性和方法)
3.store打印

2.更新视图的方法
2.1更新方法一(类组件的setState和mobx的监听)
手动挡(手动引入store,手动监听,卸载时还要取消监听)
import React, { Component } from 'react'import store from '@/store'import {autorun,reaction} from 'mobx'export default class index extends Component {constructor(props) {super(props)this.state = {a: store.a//store的初始值}}componentDidMount(){//this.mobxGuanCha = autorun(()=>{//监听store的所有数据变化-缺点:一直触发render// this.setState({// n:store.n// })//})this.mobxGuanCha = reaction (()=>[store.n],()=>{//监听store的特定(数组内的)数据变化-多写第一个参数this.setState({n:store.n})})}componentWillUnmount() {this.mobxGuanCha()//取消观察(监听的返回值就是取消监听的方法,调用即可)}render() {return (<div>{this.state.n}<button onClick={store.changeData}>+</buttom></div>)}}
bug:
当卸载组件,监听函数并没有取消,下次创建就会有多个监听。解决:在componentWillUnmount中取消观察(监听的返回值就是取消监听的方法,调用即可)
当网速慢,切换页面注销组件,请求结果回来使用setState也会报错。解决:取消异步请求不好做,投机方法在componentWillUnmount中重写setState这样请求回来后就不会触发react的setState

2.2方法二:import {observer} from ‘mobx-react’ (通过装饰器observer来监听变化)
半自动 - 手动引入store&自动检测数据更新(自动监听)
import React, { Component } from 'react'import store from '@/store'import {observer} from 'mobx-react'@observer//监听所有数据变化class Test extends Component {render() {return (<div>{store.a}<button onClick={store.changeData}>+</button></div>)}}export default Test
2.3.方法三—引入mobx-react传递store
全自动-注入(注入Provider传过来的store的属性和方法到this.props上并且自动监听)
//在根目录index.js中import store from '@/store'import {Provider} from 'mobx-react'//包裹App,传递store <Provider store={store}><App/></Provider>//报错则是react核心包或者mobx-react版本有问题或丢包https://www.cnblogs.com/inaruto/p/11342559.html组件内部:import React from 'react'import {observer,inject} from 'mobx-react'@inject('store')//注入Provider传过来的store的属性和方法到this.props上(其中'store'应该是key值)@observer //监听仓库数据变化function Test() {return (<div>{this.props.store.a}<button onClick={this.props.store.changeData}>+</buttom></div>)}export default Test
P^AU9GknXwAd*E
Amazon1123how_
