React Mobx 状态管理

4,061 阅读2分钟

如果你的Reac应用使用了Mobx来管理React的状态(state),对于组件自身可观察的state,我们可以使用 mobx-react 的 useLocalStore hook 来管理。

useLocalStore

useLocalStore<T, S>(initializer: () => T, source?: S): T

对于每一个组件实例,useLocalStore 的初始化函数只执行一次,并且在组件的整个生命周期里都有效。

useLocalStore 返回的对象的所有属性都会自动转变为 observable(可观察的),所有的 getters 会被转化为 computed 属性,所有的方法也会与 store 关联并且自动引用 mobx 的 transaction。

import React from 'react'
import { useLocalStore, useObserver } from 'mobx-react' // 6.x

export const SmartTodo = () => {
  const todo = useLocalStore(() => ({
    title: 'Click to toggle',
    done: false,
    toggle() {
      todo.done = !todo.done
    },
    get emoji() {
      return todo.done ? '😜' : '🏃'
    },
  }))

  return useObserver(() => (
    <h3 onClick={todo.toggle}>
      {todo.title} {todo.emoji}
    </h3>
  ))
}

不要解构

不能对 useLocalStore 返回的对象解构,因为解构了,就会破坏响应式。mobx 中的 observables 都是对象,一旦解构,所有的原始变量都会停留在上一个值,而不再是可观察(observable)的了。例如在上面的示例中,你可以取值 todo.title,但是不能结构:const { title } = todo

使用不可观察的变量

如果我们想要在 useLocalStore 返回的 store 中存储不可观察的变量属性,例如组件的props,可以通过 useLocalStore 的第二个参数将 props 传递给 store。

import React from 'react'
import { useLocalStore, useObserver } from 'mobx-react' // 6.x

export const SmartTodo = (props) => {
  const todo = useLocalStore(
    () => ({
      title: 'Click to toggle',
      done: false,
      toggle() {
        todo.done = !todo.done
      },
      get emoji() {
        return todo.done ? '😜' : '🏃'
      },
    }),
    // 通过 useLocalStore 的第二个参数传递无需观察的变量
    props
  )

  return useObserver(() => (
    <h3 onClick={todo.toggle}>
      {todo.title} {todo.emoji}
    </h3>
  ))
}

关于全局 store

useLocalStore 的命名看着像是只能用在组件内,但实际上,完全可以使用它再加上 React Context 来处理全局的store。例如,可以设置一堆本地的 store,然后将它们组装在一个根对象中,并在React Context的帮助下在应用程序中传递。

参考文档:mobx-react.js.org/state-local