MobX仅观察反应组件中可观察到的特定现象

时间:2020-10-02 12:01:28

标签: javascript reactjs mobx mobx-react

我的应用程序中有一些组件需要遵循全局控制的动态布局。这意味着,如果我的应用程序中的某些内容(例如,它是响应上下文或用户主题)发生更改,则每个组件都需要使用新的布局进行重新渲染。布局如下:

A | B | C C C C | D

为了封装来自客户端组件的样式和逻辑,我创建了Template组件,该组件从MobX存储观察ResponsiveContext并在更改时重新呈现。因此,每个需要遵循布局的组件实际上都会渲染Template并通过prop将React元素传递给它。但是可能有很多C或只有1个,所以我没有手动传递C而是传递数据,而是回调以呈现它,而Template使用回调准备和映射数据。从客户端的角度来看,是这样的:

function Client() {
  return <Template
    a={<div>A</div>}
    b={<div>B</div>}
    d={<div>D</div>}
    cData={[1, 2, 3, 4]}
    cRenderFunction={el => <div key={el}>{el}</div>}
  />
}

和模板组件如下所示:

function Template(props) {
  const size = useUiStore().responsiveContext.size;

  return <div>
    <div>{props.a}</div>
    <div>{props.b}</div>
    <div>{prepareData(size, props.cData).map(props.cRenderFunction)}</div>
    <div>{props.d}</div>
  </div>
}

问题是.map(props.cRenderFunction)仅创建React元素而不是React节点,因此客户端观察到的所有内容也被observer(Template)观察到,从而产生了另一次重新渲染:observer(ClientComponent)读取了可观察到的{{1 }}本身,然后在函数x中进行渲染,该函数随后在渲染cRenderFunction时被调用-因此2个组件观察到TemplatexTemplate)。现在每次ClientComponent突变x重新渲染,然后Template突变,然后再次重新渲染ClientComponent

我看到两种解决方案:

  • 仅观察数据的特定部分(在我们的示例中为Template)。以前我会使用来自mobx-react的ResponsiveContext钩子,但现在已弃用它,我不知道如何替换它。代码如下:
useObserver
  • 渲染React节点而不是元素,以便在渲染其他组件时可以读取来自客户端的数据,这可以防止function Template(props) { const uiStore = useUiStore(); const size = useObserver(() => uiStore.responsiveContext.size); // the same as before } 观察到它。

第二个选项对我来说似乎是一种解决方法,我认为这违反了性能,因为我需要创建成千上万个定期定期更新的元素。

哪个选项是最好的?如果是第一个,该如何替换不推荐使用的Template API?如果是第二个,如何创建新的React节点并从客户端而不是useObserver组件设置密钥?因为我看到的唯一方法是将另一个函数传递给Template,该函数将基于数据生成密钥。

0 个答案:

没有答案