0

如下图所示,我有一个基本的反应上下文设置。

我的愿望是消耗上下文的子组件应该只在上下文数据更改时重新渲染,但我发现情况并非如此。

如果我更新与上下文无关的 call setData2,则会触发状态更新Container,随后会触发重新计算并导致消费子更新。

有问题的子组件已经在使用React.memo,所以它只会在它的useContext钩子导致它时更新。但是上下文会在更新时Container更新,即使没有data1改变。

有可能解决这个问题吗?

const Container = () => {
  const [data1, setData1] = useState(...);
  const [data2, setData2] = useState(...);

  return (
    <MyContext.Provider value={{ data1, setData1 }}>
     // child component hierarchy
    </MyContext.Provider>
  );
};
4

2 回答 2

1

为了防止子组件在上下文状态更改时重新渲染,您应该通过childrenprop 将子组件传递给上下文提供程序:

// Define the provider component
const MyContextProvider = ({ children }) => {
  const [data1, setData1] = useState(...);
  const [data2, setData2] = useState(...);

  return (
    <MyContext.Provider value={{ data1, setData1 }}>
     {children}
    </MyContext.Provider>
  );
};

然后在你的应用程序的某个地方,渲染提供者:

// Render the provider component
const App = () => {
  return (
    <MyContextProvider>
     // child component hierarchy
    </MyContextProviderr>
  );
};

要访问提供者状态,孩子应该使用useContext(MyContext)钩子。

没有必要使用React.memo. React 知道,在使用childrenprop 渲染子组件时,子组件不需要重新渲染,因为它们不可能受到本地状态变化​​的影响。

于 2020-09-15T04:55:23.277 回答
0

您可以将不想重新渲染(由其他不相关状态触发)的子组件useMemo与相关依赖项一起包装 - 仅针对该子组件

const Container = () => {
  const [data1, setData1] = useState(...);
  const [data2, setData2] = useState(...);

  const rerenderInCertainConditions = useMemo(() => (
    <MyContext.Provider value={{ data1, setData1 }}>
     // child component hierarchy
    </MyContext.Provider>
  ), [data1])

  return (
    {rerenderInCertainConditions}
  );
};

Codesandbox 演示

编辑 goofy-kare-wgn45

于 2020-09-15T04:25:25.453 回答