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.js
import {observable,autorun,reaction,action,computed} from 'mobx'
class Store {
// observable监听数据变化;
@observable a=5;
@observable b=21;
// action修改
@action changeA=()=>{//箭头函数,为了使用this
this.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=100
console.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_