引言
公司使用的状态管理是mobx,于是抽空看看了文档和资料;上手后发现mobx相对于redux而言十分的轻量,状态管理过程和vuex十分的相似。
快速使用
1.安装
npm i mobx mobx-react-lite
2.创建store文件
在src下创建store/index.js
核心参数
makeObservable(target,{
data1:observable,//observable指定需要监听的数据
data2:observable,
方法1:action//action指定监听修改数据的方法
})
makeObservable官方解释:这个函数可以捕获已经存在的对象属性并且使得它们可观察。任何 JavaScript 对象(包括类的实例)都可以作为 target
被传递给这个函数。
很明显,makeObservable的第一个参数传递待观察的实例对象,第二个参数用于配置监听哪些实例对象属性以及监听修改对象属性的方法。
import {action, makeObservable, observable} from 'mobx'
class Counter {
count = 0
constructor(){
makeObservable(this, {
count: observable,//observable指定监听的属性
increment: action,//action指定修改属性的方法
decrement: action//
})
}
increment(num){
this.count += num
}
decrement(num){
this.count -= num
}
}
const counter = new Counter()
export default counter
3.组件中使用
直接导入store就可以在组件中使用数据和修改数据的方法。
import store from "./store/index"
import { observer } from 'mobx-react'
function App() {
const {cart,count} = useStore()
return (
<div className="App">
<div>count:{store.count}</div>
<div onClick={()=>store.increment(1)}>add</div>
<div onClick={()=>store.decrement(1)}>del</div>
<div>
);
}
export default observer(App);
4. computed计算属性
computed计算属性和vue的一毛一样,当监听的数据发生改变时,会自动执行计算相关的计算属性。如果数据未更新则走缓存,不会触发二次执行。
import {action, makeObservable, observable} from 'mobx'
class Counter {
count = 0
constructor(){
makeObservable(this, {
count: observable,//observable指定监听的属性
increment: action,//action指定修改属性的方法
decrement: action//
autoADD:computed//computed指定计算属性方法
})
}
increment(num){
this.count += num
}
decrement(num){
this.count -= num
}
get autoADD() {
return this.count+1
}
}
const counter = new Counter()
export default counter
组件中使用
import store from "./store/index"
import { observer } from 'mobx-react'
function App() {
const {cart,count} = useStore()
return (
<div className="App">
<div>count:{store.count}</div>
<div onClick={()=>store.increment(1)}>add</div>
<div onClick={()=>store.decrement(1)}>del</div>
<div>测试计算属性:{store.autoADD}</div>
<div>
);
}
export default observer(App);
5. 异步修改数据
mobx异步修改数据的方式是巨他妈简化了,直接使用runInAction方法将修改数据的操作包裹起来就ok了
import {action, makeObservable, observable} from 'mobx'
class Counter {
count = 0
constructor(){
makeObservable(this, {
count: observable,//observable指定监听的属性
increment: action,//action指定修改属性的方法
decrement: action//
asyncAdd:action,
autoADD:computed//computed指定计算属性方法
})
}
increment(num){
this.count += num
}
decrement(num){
this.count -= num
}
asyncAdd() {
setTimeout(() => {
runInAction(() => {
this.count+=100
})
}, 2000);
}
}
const counter = new Counter()
export default counter
6.模块化
数据模块化是每个状态管理都需要考虑设计的,随着业务的逐步拓展,项目需要按指定业务需求进行拆分成各个子模块。
1.创建两个模块cart和count
src/store目录下创建两个文件夹count和cart分别保存两个模块的数据
2.count模块:store/count/index.js
import {action, makeObservable, observable,computed,runInAction} from 'mobx'
class Counter {
constructor(){
makeObservable(this, {
count: observable,
increment: action,
decrement: action,
})
}
count = 0
increment(num){
this.count++
}
decrement(num){
this.count++
}
const counter = new Counter()
export default counter
3.cart模块:store/cart/index.js
import {action, makeObservable, observable,computed,runInAction} from 'mobx'
class Counter {
constructor(){
makeObservable(this, {
count: observable,
increment: action,
decrement: action,
})
}
count = 0
increment(num){
this.count++
}
decrement(num){
this.count++
}
const counter = new Counter()
export default counter
4. store/index.js:对模块的统一管理
将各个模块绑定到一个实例对象上,借助useContext将实例对象保存
import React from 'react';
import Cart from "./cart"
import Count from './count'
class Store {
cart
count
constructor(){
this.cart = Cart;
this.count = Count;
}
}
const store = new Store()
const context = React.createContext(store)
const useStore = () => React.useContext(context)
export default useStore
5.组件中使用
import useStore from "./store/index"
import { observer } from 'mobx-react'
function App() {
const {cart,count} = useStore()
return (
<div className="App">
<div>
<div>count模块 {count.count} </div>
<div onClick={()=>count.increment(10)}>add</div>
<div onClick={()=>count.asyncAdd()}>异步修改</div>
</div>
<div>--------</div>
<div>
<div>cart模块 {cart.count}</div>
<div onClick={()=>cart.increment(100)}>add</div>
</div>
</div>
);
}
export default observer(App);
总结
对比Redux,Mobox有以下特点
- 简洁性:redux有严格的执行顺序,需要定义dispatch函数进行数据把控,而mobox定义后,直接使用,直接修改
- 数据直接修改:redux修改引用数据时,不能直接修改,需要解构赋值修改对象的地址,而mobx修改引用数据时是可以直接修改的。
- 异步直接处理:redux对于数据的异步操作需要依赖中间件完成,而mbx借助方法直接修改
- 适用性:实践表明,在规模不大的项目中使用mobx是十分舒服的事情。
原文链接:https://juejin.cn/post/7242927398295322661 作者:前端兰博