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
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
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.
In this scenario using
useMemo
is very debatable becausecounterColor
is not heavy in calculation. Using counterColor directly is probably more efficient than wrapping it insideuseMemo
.