切换上下文会导致整个组件的重新渲染

时间:2020-10-27 17:37:22

标签: javascript reactjs

我目前正面临挑战,我的Layout.js中有两个不同的组件 零件。这两个组成部分必须彼此“共享”道具。为了解决这个问题,我添加了一个ContextProvider IntegrationProvider

但是,现在我遇到了问题,无论何时currentElement.type发生变化(因此IntegrationProvider发生变化),整个Layout组件都会重新呈现。我目前的最佳想法是为所有集成创建一个ContextProvider。但是,这将导致其他集成中出现许多不必要的道具。你有更好的主意吗?

Space.js

<IntegrationProvider>
  <Layout
    [props...]
  />
</IntegrationProvider>

IntegrationProvider.js

const integrationProvider = {
  [INTEGRATION_TYPE.DAILY]: IntegrationProviderDaily,
};

const IntegrationProvider = ({ children }) => {
  const currentElement = useSelector(getCurrentElement);

  /**
   * Return IntegrationProvider if available, otherwise just return children.
   */
  const getIntegrationProvider = () => {
    const IntegrationProvider = integrationProvider[currentElement?.type];

    return IntegrationProvider ? (
      <IntegrationProvider children={children} />
    ) : (
      children
    );
  };

  return getIntegrationProvider();
};

export default IntegrationProvider;

IntegrationProviderDaily.js

const IntegrationProviderDaily = ({ children }) => {
  const dailyRef = useRef();
  [...]

  const muteUser = (userId, device) => {
    // Do stuff
  };

  return (
    <DailyContext.Provider
      value={{
        dailyRef,
        muteUser,
      }}
    >
      {children}
    </DailyContext.Provider>
  );
};

export default IntegrationProviderDaily;

1 个答案:

答案 0 :(得分:0)

完全刷新的原因是因为您正在将IntegrationProvider分配给变量。这意味着您在每个渲染上都具有该组件的不同实例,而不是同一组件,但是具有更新的value道具。

const IntegrationProvider = integrationProvider[currentElement?.type];

另一方面,我发现此代码难以阅读,因为您的局部变量与组件本身具有相同的名称。那不是造成问题的原因,但是应该避免。

您应该考虑让一个上下文提供者具有两个可能的值,或者让它们完全分开。老实说,我对这对您的工作感到困惑。您说这两个上下文具有不同的值。因此,当孩子从上下文访问值时,它如何知道所得到的呢?