如果使用 Hook 重新渲染父级,则防止子级重新渲染

Jea*_*ert 5 memoization react-native react-hooks use-reducer react-memo

我的 bestSellerDummy 数据不会更改,因此我想防止在父级重新呈现时重新呈现相同的产品子级。我尝试在父级中使用 useMemo 并在子级中使用 React.memo 但没有运气,每次父级重新渲染时它仍然显示日志“渲染产品组件..”。我在这里缺少什么?请指教。

注意:每次我在 Product 组件中调用 addToCart 函数(CartContext 的)时,预计都会重新呈现父级。

我正在使用 CartContext,也许与此有关,我不确定。这是沙箱:https://codesandbox.io/s/dazzling-moore-po1c6 ?file=/src/App.js

主页.tsx

const [bestSellerDummy] = useState(
  [...new Array(5)].map((item, key) => ({
    id: key,
    imageUri:'https://1.jpg',
    name: 'My Dummy 1',
    price: 25,
  })),
);

const bestSellers = useMemo(() => {
  return bestSellerDummy.map((productDummy, key) => {
    return (
      <Product key={key} product={productDummy} />
    );
  });
}, [bestSellerDummy]);

return (
  ...
  {bestSellers}
  ...
)
Run Code Online (Sandbox Code Playgroud)

产品.tsx

const Product: FunctionComponent<IProductProps> = (
  productProps,
) => {
  ...
  console.log('Rendering Product component..');
  ...
}

export default React.memo(Product);
Run Code Online (Sandbox Code Playgroud)

===编辑:我的答案版本===

最后!在尝试了useCallback, useMemo,fast-memoize插件之后..最适合我的是useReducer在 Context 中使用结合使用React.memo. 我认为这是优化子组件最干净、最优雅的方式。工作沙箱在这里:https ://codesandbox.io/s/eloquent-albattani-8x7h9?file=/src/App.js

don*_*han 3

由于您正在使用useContext,您的组件将始终重新渲染。

当组件上方最近的 <MyContext.Provider> 更新时,此 Hook 将触发重新渲染,并将最新的上下文值传递给该 MyContext 提供程序。即使祖先使用 React.memo 或 shouldComponentUpdate,重新渲染仍然会使用 useContext 从组件本身开始发生。

参考: https: //reactjs.org/docs/hooks-reference.html#usecontext

我试图使用文档中指出的第二种策略重构您的代码: https: //github.com/facebook/react/issues/15156#issuecomment-474590693

然而,我很快意识到该addToCart函数具有cartItems其依赖性,因此每当cartItems发生变化时,addToCart就不可避免地会发生变化,因为每个Product组件都使用addToCart函数。

这导致我使用了,useReducer因为React 保证它dispatch是稳定的并且在重新渲染期间不会改变。

这是正在运行的 Codesandbox:https://codesandbox.io/s/red-feather-dc7x6? file=/src/App.js:786-797