将 Mobx observables 与 React 依赖项结合使用

Using Mobx observables with React dependencies

Mobx 文档说使用模式 useEffect(reaction(..)) 来跟踪可观察到的变化,这对我来说像是杂交。使用 react dependencies array 来实现它有什么问题?我做了一个基本测试,它按预期工作:

const Hello = observer(() => {
  const {
    participantStore: { audioDisabled },
  } = useStores();
  useEffect(() => {
    console.log('changed', audioDisabled);
  }, [audioDisabled]);

  return <h1>TEST ME</h1>;
});

在 MobX 中使用 useEffectuseMemo 等 React 东西绝对没有问题。您只需要列出所有依赖项,如果它们很多,使用 reactionautorun.

可能更容易

所以请随意使用您喜欢的任何方式。

混合使用 MobX observables 和 hooks 基本上是无痛的,但是有一些事情需要注意。最需要注意的是,将可观察值添加到 dependencies 数组并不总是会触发效果。在表面之下,MobX 对象和数组是对代理对象的稳定引用。因此,即使 observable 的值发生变化,useEffect 挂钩并不总能捕捉到该变化。

解决方案很简单,在 React Integration: useEffect and observables 下的 MobX 文档中有概述:

Using useEffect requires specifying dependencies. With MobX that isn't really needed, since MobX has already a way to automatically determine the dependencies of an effect, autorun. Combining autorun and coupling it to the life-cycle of the component using useEffect is luckily straightforward

实际上,这看起来像:

const Hello = observer(() => {
  const { participantStore } = useStores();
  useEffect(() => autorun(() => {
    console.log('changed', participantStore.audioDisabled);
  }), []);

  return <h1>Audio is {!participantStore.audioDisabled && 'NOT '}Disabled</h1>;
});

有几点需要注意:

  1. 如果您还处理本地状态(通过 useState 或其他挂钩),您 需要将它们包含在依赖项数组中。
  2. 一定要return useEffect 挂钩中的自动运行函数。这确保侦听器在组件卸载时 de-registered。
  3. 您的 linter 可能会因缺少依赖项而感到沮丧。我不会以任何一种方式提出建议,因为无论是全局禁用它还是保持启用并禁用它都有利有弊 per-line。这在很大程度上取决于您要处理多少本地状态。