Home > OS >  How to force React.memo render component only once (on initial load)?
How to force React.memo render component only once (on initial load)?

Time:06-24

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:

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?

CodePudding user response:

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.

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>
  );
};

CodePudding user response:

There are few you can achieve this, of course by using memoization. But first of all I suggest you to move ChildComponent definition outside of the ParentComponent. Both ways require you to wrap ChildComponent in React.memo, like you did, so that part is okay.

First way is to be sure that value(reference) for items prop is stable, if you want to avoid unnecessary rerenders of child componnet. So the solution would be to wrap items objectin useMemo and to compute it only once so reference become stable.

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. More about this can be found here react memo

  • Related