skip to Main Content

Counter component is getting render twice everytime on change of counter prop. I tried to use memo but seems it does not work. My aim is to reduce rendering on change of props. Can anybody please help me to solve this problem.

import React, {memo, useState } from "react";
import "./styles.css";

const Counter = memo(({ counter }) => {
  alert("counter++++");
  const func = (counter) => {
    // alert(counter);
    if (counter >= 0 && counter <= 5) return "Red";
    else if (counter > 5 && counter <= 10) return "Green";
    return "Blue";
  };
  return <h2>{func(counter)}</h2>;
});
export default function App() {
  const [counter, setCounter] = useState(0);
  return (
    <div>
      <h1>value of Counter {counter}</h1>
      <Counter counter={counter} />
      <button onClick={() => setCounter(counter + 1)}>Increment by 1</button>
      <button onClick={() => setCounter(counter - 1)}>Decrement by 1</button>
    </div>
  );
}```

2

Answers


  1. I’ve noticed that the Counter component renders twice every time the counter prop changes, specifically when React.StrictMode is enabled in development mode. This behavior might seem concerning at first, but it’s actually an intentional feature of React.

    During development, React intentionally renders components twice when React.StrictMode is enabled. This double invocation mechanism helps detect potential issues like impure render methods or side effects. However, it’s important to note that this behavior is exclusive to development mode; in production mode, where React.StrictMode is disabled, the double rendering does not occur. React’s optimizations ensure that rendering is efficient and streamlined in production.

    For reference- https://react.dev/reference/react/useMemo#my-calculation-runs-twice-on-every-re-render

    Login or Signup to reply.
  2. Why not use useMemo ?
    I don’t really see a use-case for React.memo here.
    Count changes on every interaction, right?
    As others have already mentioned, rendering twice is intended in dev when using React.StrictMode around your App.
    Usually, it is best not to reduce the amount of renders, but to reduce the amount of calculations that happen within a render first.

    import React, {useMemo, useState } from "react";
    import "./styles.css";
    
    const counterColor = (count) => {
       alert("color change");
       if (counter >= 0 && counter <= 5) return "Red";
       else if (counter > 5 && counter <= 10) return "Green";
       return "Blue";
    };
    
    const Counter = ({ count }) => {
      const color = useMemo(() => counterColor(count), [count]);
      
      return <h2>{color}</h2>;
    };
    export default function App() {
      const [counter, setCounter] = useState(0);
      return (
        <div>
          <h1>value of Counter {counter}</h1>
          <Counter count={counter} />
          <button onClick={() => setCounter(counter + 1)}>Increment by 1</button>
          <button onClick={() => setCounter(counter - 1)}>Decrement by 1</button>
        </div>
      );
    }
    

    In this scenario using useMemo is very debatable because counterColor is not heavy in calculation. Using counterColor directly is probably more efficient than wrapping it inside useMemo.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search