MobX是react的状态管理库之一。相比Redux有mutation, action, dispatch等概念. mobx则更加简洁, 更符合对store增删改查的操作概念。在eact的版本迭代中,mobx也经历了数次更新迭代。它们的版本兼容性问题,以及mobx的使用问题,想必初学者都会踩坑。下面将对这些问题一一梳理。
核心概念
首先,来快速过一遍mobx5的核心概念。Mobx5中文文档
observable
mobx.observable
将对象的属性变为可观察的属性。这里的对象涵盖对象,数组和类实例。写法分为两种:第一种,将有状态的对象用observable
包裹起来;第二种,对可观测的属性使用装饰器@observable
。
observable({
count: 0
});
class Store {
@observable count = 0
}
action
mobx.action
用来定义更改状态的函数。写法也分为两种。第一种,将改变状态的函数用action
包裹起来;第二种,对改变状态的函数加装饰器@action
。
action(() => {
store.count++
})
@action setCount = () => {
this.count++
}
observer
observer 函数/装饰器可以用来将 React 组件转变成响应式组件。observer 是由单独的 mobx-react
包提供的。 写法同样也有两种。第一种,将组件用observer
包裹起来;第二种,对组件加装饰器@observer
。
mobx.autorun
包装了组件的 render 函数以确保任何组件渲染中使用的数据变化时都可以强制刷新组件。
observer(function Home () {
return (
...
)
})
@observer
class Home extends React.Component{
render () {
return (
...
)
}
}
class组件
下面来讲讲针对class组件使用mobx的最佳实践。
Mobx5
在版本兼容性上,Mobx5
需要配合react16.x
使用。mobx5搭配react17会报错。
Mobx5.x
通常采用装饰器的写法,包括@observable
, @computed
, @action
。
// store.js
import {observable, action} from 'mobx'
class Store {
@observable count = 0
@action setCount = () => {
this.count++
}
}
export default new Store()
// home.js
import React from 'react'
import {observer} from 'mobx-react'
import store from './store'
@observer
class Home extends React.Component{
render () {
return (
<div onClick={store.setCount}>detail{store.count}</div>
)
}
}
export default Home
Mobx6
Mobx6
可以配合react17
使用。
Mobx6
在store.js
中不需要再写这些装饰器了,直接使用makeObservable
或者makeAutoObservable
。通常用在类的构造函数中。
makeObservable
makeObservable(target, annotations?, options?)
捕获target对象的属性,并使它们可观察。在class构造函数中,第一个参数为this。
import {makeObservable, observable, action} from 'mobx'
class Store {
constructor () {
makeObservable(this, {
count: observable,
setCount: action
})
}
count = 0
setCount = () => {
this.count++
}
}
export default new Store()
makeAutoObservable
makeAutoObservable(target, overrides?, options?)
makeAutoObservable与makeObservable类似,不同点是它会默认推断所有属性,比makeObservable更容易维护。注意:makeAutoObservable不能用于super或subclassed的类。
import {makeAutoObservable} from 'mobx'
class Store {
constructor () {
makeAutoObservable(this)
}
count = 0
setCount = () => {
this.count++
}
}
export default new Store()
函数组件
在react hooks的应用中,hooks的功能已经非常强大,为什么还要用mobx呢?这篇文章讲的比较深入了,感兴趣的童靴点击此链接 Hooks 邂逅 Mobx,代码变得更丝滑了
Mobx5
由于装饰器写法不支持函数式组件,可以用observable
和observer
函数写法。
mobx5在函数组件的一般用法如下。
import React from 'react'
import { observable } from 'mobx'
import { observer } from 'mobx-react'
const store = observable({
count: 0,
setCount: () => {
store.count++
}
})
export default observer(function Detail () {
return (
<div onClick={store.setCount}>detail: {store.count}</div>
)
})
Mobx6
Mobx6
提供了useLocalObservable
, useObserver
HOC用法。
useLocalStore已经废弃,官方推荐使用useLocalObservable
import React from 'react'
import {useLocalObservable, useObserver} from 'mobx-react'
export default function Home () {
const store = useLocalObservable(() => ({
count: 0,
setCount () {
this.count++
}
}))
return useObserver(() => (
<div onClick={store.setCount}>home{store.count}</div>
))
}
除了使用useObserver
钩子函数,还可以使用Observer
import React from 'react'
import {Observer, useLocalObservable} from 'mobx-react'
export default function Home () {
const store = useLocalObservable(() => ({
count: 0,
setCount () {
this.count++
}
}))
return <Observer>
{
() => <div onClick={store.setCount}>home{store.count}</div>
}
</Observer>
}
最后
以上。表述有误的地方,欢迎童鞋指正。