为什么 Mobx 有用?
Why Mobx is useful?
MobX web 教程真的很难过。有人能用简单的英语向我解释为什么当 React 已经有了状态管理系统时 MobX 很有用吗?
Mobx 是一个应用函数式反应式编程进行状态管理的库,它与 OOP 中的观察者模式非常相似。
对于具有复杂状态的组件,它比常规的 React 状态管理更方便。
- 有了 mobx,你不需要多次使用 useState。你可以将状态存储在一个对象中,它看起来就像一个普通的 js 对象(但实际上是一个代理对象,由 getter 和 setter 组成)。您可以一次更改 mobx 状态对象,而不是多次调用 setState。
- Mobx 状态对象不是不可变的,这对于嵌套状态更方便,因为您不需要一路创建浅拷贝来确保不可变性
- 您可以从组件中解耦一些逻辑,从而简化它(计算,类似于 useMemo)。
- Mobx 比 redux 更简单,也更高效。
这是一个常规的反应示例:
const Widgets = (props) => {
const [widgets, setWidgets] = useState([])
const [status, setStatus] = useState('loading') // loading, error, loaded
const onLoaded = (widgets) => {
setWidgets(widgets)
setStatus('loaded')
}
const onClose = (widget) => {
const index = widgets.findIndex(currWidget => widget === currWidget)
const nextWidgets = [...widgets]
nextWidgets[index] = { ...nextWidgets[index] }
nextWidgets[index].status = 'animatingOut'
setWidgets(nextWidgets)
}
const hasActiveWidgets = useMemo(() => widgets.some(widget => widget.isActive), [widgets])
if(hasActiveToasts){
// something
}
...
}
这是与 mobx 相同的示例:
class State {
constructor(){
makeAutoObservable(this) // use second parameter, to override, which properties to track and how
}
widgets: []
status: 'loading'
hasActiveWidgets: () => this.widgets.some(widget => widget.isActive)
}
const Widgets = observer((props) => {
const state = useMemo(() => new State(), [])
const onLoaded = action((widgets) => {
state.widgets = widgets
state.status = 'loaded'
})
const onClose = action((widget) => widget.status = 'animatingOut')
if(state.hasActiveWidgets()){ // this causes rerender, whenever this function result changes (if state was changed inside action or runInAction)
// something
}
...
})
此外,您可以将 mobx 状态放入 React 上下文中,并与多个组件共享。这样它可以像 redux store 一样工作。
MobX web 教程真的很难过。有人能用简单的英语向我解释为什么当 React 已经有了状态管理系统时 MobX 很有用吗?
Mobx 是一个应用函数式反应式编程进行状态管理的库,它与 OOP 中的观察者模式非常相似。
对于具有复杂状态的组件,它比常规的 React 状态管理更方便。
- 有了 mobx,你不需要多次使用 useState。你可以将状态存储在一个对象中,它看起来就像一个普通的 js 对象(但实际上是一个代理对象,由 getter 和 setter 组成)。您可以一次更改 mobx 状态对象,而不是多次调用 setState。
- Mobx 状态对象不是不可变的,这对于嵌套状态更方便,因为您不需要一路创建浅拷贝来确保不可变性
- 您可以从组件中解耦一些逻辑,从而简化它(计算,类似于 useMemo)。
- Mobx 比 redux 更简单,也更高效。
这是一个常规的反应示例:
const Widgets = (props) => {
const [widgets, setWidgets] = useState([])
const [status, setStatus] = useState('loading') // loading, error, loaded
const onLoaded = (widgets) => {
setWidgets(widgets)
setStatus('loaded')
}
const onClose = (widget) => {
const index = widgets.findIndex(currWidget => widget === currWidget)
const nextWidgets = [...widgets]
nextWidgets[index] = { ...nextWidgets[index] }
nextWidgets[index].status = 'animatingOut'
setWidgets(nextWidgets)
}
const hasActiveWidgets = useMemo(() => widgets.some(widget => widget.isActive), [widgets])
if(hasActiveToasts){
// something
}
...
}
这是与 mobx 相同的示例:
class State {
constructor(){
makeAutoObservable(this) // use second parameter, to override, which properties to track and how
}
widgets: []
status: 'loading'
hasActiveWidgets: () => this.widgets.some(widget => widget.isActive)
}
const Widgets = observer((props) => {
const state = useMemo(() => new State(), [])
const onLoaded = action((widgets) => {
state.widgets = widgets
state.status = 'loaded'
})
const onClose = action((widget) => widget.status = 'animatingOut')
if(state.hasActiveWidgets()){ // this causes rerender, whenever this function result changes (if state was changed inside action or runInAction)
// something
}
...
})
此外,您可以将 mobx 状态放入 React 上下文中,并与多个组件共享。这样它可以像 redux store 一样工作。