Andry
Andry

Reputation: 16845

Why is the (memoized) child component re-rendering?

I have two React functional components: C1 and C2. C2 is nested inside C1:

const C2 = () => {
  console.log("C2 Render");
  return (
    <div>I am Component 2</div>
  );
};

const C1 = () => {
  const [text, setText] = useState("Hello");
  const MC2 = React.memo(C2, () => true);
  
  return (
    <div className="box">
      <h1>The Button</h1>  
      <button
        onClick={() => {
          setText(`${text} b`);
        }}
        className="button">
          Click me
       </button>
      <div>
        {text}
      </div>
      <MC2 />
    </div>
  );
}

CodePen here.

The problem

I know that a component gets re-rendered under different situations. Among those is the one when the parent re-renders.

That is why I am using a memoized component around C2. But still I can see the console displaying "C2 Render" every time I click the button.

Why?

Upvotes: 0

Views: 802

Answers (1)

e.a.
e.a.

Reputation: 948

C1 rerender because of state chnage, so your memoized component is redeclared every time. just wrap C2 in a React.memo() & you would not see the rerenders

const MC2 = React.memo(() => {
  console.log("C2 Render");
  return (
    <div>I am Component 2</div>
  );
}, () => true);

or if you want to memoize only one useCase put it outside the C1 component and have that component memoized:

const C2 = () => {
  console.log("C2 Render");
  return (
    <div>I am Component 2</div>
  );
};

const MC2 = React.memo(C2, () => true);

& used it like this:

const C1 = () => {
  const [text, setText] = useState("Hello");
  
  return (
    <div className="box">
      <h1>The Button</h1>  
      <button
        onClick={() => {
          setText(`${text} b`);
        }}
        className="button">
          Click me
       </button>
      <div>
        {text}
      </div>
      <MC2 />
    </div>
  );
}

Upvotes: 2

Related Questions