如果父组件更新反应 js 中的上下文或状态,如何停止重新渲染子组件?

how to stop re-rendering of child component if parent update the context or state in react js?

如果父组件在 React js 中更新上下文或状态,如何停止重新渲染子组件?

我已经在使用 React.memo 但它仍在重新渲染。

这是我的子组件

const Ab = () => {
  console.log("---ff-ddd");
  const pageContext = useContext(PageContext);

  useEffect(() => {
    setTimeout(() => {
      pageContext.updateGlobalMenu({});
    }, 5000);
  }, []);
  return <div>ddd</div>;
};

export default React.memo(Ab);

我正在更新上下文。我希望它更新上下文值但不重新渲染子组件

export default function IndexPage() {
  const [globalMenu, setGlobalMenu] = useState("");

  const updateGlobalMenu = (menuContent) => {
    setGlobalMenu(menuContent);
  };

  return (
    <PageContext.Provider
      value={{
        updateGlobalMenu
      }}
    >
      <Ab />
    </PageContext.Provider>
  );
}

这是我的代码

https://codesandbox.io/s/friendly-bartik-3cnqvf?file=/pages/index.js:156-470

如果你看到它打印两次控制台。这意味着它正在重新渲染两次

如果 PageContext 的值发生变化,那么任何使用该上下文的组件(包括 Ab)都将呈现。 React.memo 无法阻止。在您的情况下,您正在更改每个渲染的值,因此您有空间通过记忆上下文值来改进它。这样,除非需要,否则该值不会改变:

export default function IndexPage() {
  const [globalMenu, setGlobalMenu] = useState("");

  const updateGlobalMenu = useCallback((menuContent) => {
    setGlobalMenu(menuContent);
  }, []);

  const value = useMemo(() => ({
    updateGlobalMenu
  }), [updateGlobalMenu]);

  return (
    <PageContext.Provider value={value}>
      <Ab />
    </PageContext.Provider>
  );
}

除了上一个答案的记忆之外,您还可以将状态的“api”和“数据”部分拆分为两个不同的提供者。

updateGlobalMenu 将在 PageContextAPI 提供商中,globalMenu 将在 PageContextData 提供商中。这样当您更新数据时,只有提供数据的提供者才会 re-rendered.

看看这篇文章,我在这里详细介绍了这个技术:https://www.developerway.com/posts/how-to-write-performant-react-apps-with-context