简体   繁体   English

如何仅强制 React.memo 渲染组件一次(在初始加载时)?

[英]How to force React.memo render component only once (on initial load)?

Inside my parent component I have a child component that I need to render only once - at the very beginning.在我的父组件中,我有一个子组件,我只需要渲染一次 - 在最开始时。 Because the data inside wont ever change until next page reload.因为在下一页重新加载之前,里面的数据永远不会改变。 What I try to do is somehow force React.memo to prevent rendering of this child component:我尝试做的是以某种方式强制 React.memo 阻止渲染这个子组件:

const ParentComponent = (props) => {

    const ChildComponent = React.memo(({items}) => {
        const { param1, param2, param3 } = items;
        ...
        return (<Box>..</Box>);
    }, (prev, nxt) => true); // Here I try to force no render
    
    return (<Box>
          <ChildComponent items={{
             param1: 'some val..',
             param2: 'some val..',
             param3: 'some val..',
          }} />
          ...
       </Box>);
}

But child component still re-renders on each parent state change.但是子组件仍然会在每次父状态更改时重新渲染。 Am I doing something wrong?难道我做错了什么?

First of all, defining a component inside another component is a bad practice, because首先,在另一个组件中定义一个组件是一种不好的做法,因为

  1. Performance issue, as you are experiencing性能问题,正如您所遇到的
  2. You can't reuse the component --> poor scalability您不能重用组件-> 可扩展性差
  3. By changing the child component, you have to update the source code of the parent component and vice versa --> easy to introduce side effects通过更改子组件,您必须更新父组件的源代码,反之亦然-->容易引入副作用

So to make your life easier, extract the ChildComponent .因此,为了让您的生活更轻松,请提取ChildComponent

const ChildComponent = props => {
  return (
    <Box>
      {/* do whatever you like */}
    </Box>
  );
};

export default memo(ChildComponent);
const ParentComponent = props => {
  const items = {
    param1: 'some val..',
    param2: 'some val..',
    param3: 'some val..',
  };

  return (
    <Box>
      <ChildComponent 
        items={items} 
        // You can also pass other props from the ParentComponent, in case ChildComponent needs it
      />
    </Box>
  );
};

There are few you can achieve this, of course by using memoization.当然,很少有人可以通过使用 memoization 来实现这一点。 But first of all I suggest you to move ChildComponent definition outside of the ParentComponent .但首先我建议您将ChildComponent定义移到ParentComponent之外。 Both ways require you to wrap ChildComponent in React.memo, like you did, so that part is okay.这两种方式都要求您像您所做的那样将ChildComponent包装在 React.memo 中,所以这部分是可以的。

First way is to be sure that value(reference) for items prop is stable, if you want to avoid unnecessary rerenders of child componnet.第一种方法是确保items道具的值(参考)是稳定的,如果你想避免不必要的子组件重新渲染。 So the solution would be to wrap items objectin useMemo and to compute it only once so reference become stable.因此解决方案是将items对象包装在 useMemo 中并仅计算一次以使引用变得稳定。

Second way is to use second parameter for React.memo function, and to pass custom isEqual function in order to determine when your prop has changed, eg to perform deep equality check on subsequent values for items prop so you can avoid unnecessary rerenders.第二种方法是使用 React.memo 函数的第二个参数,并传递自定义isEqual函数以确定您的道具何时更改,例如对items道具的后续值执行深度相等检查,以避免不必要的重新渲染。 More about this can be found here react memo更多关于这个可以在这里找到反应备忘录

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM