I am currently working with React components, and I’m experiencing an issue with shared state in the Area component. The component has a count state, and the problem arises when multiple instances of the component are created.
function Area({ title }) {
const [count, setCount] = useState(0);
return (
<div>
<h2>current area : {title}</h2>
<div>
<button type="button" onClick={() => setCount(count + 1)}>
+1
</button>
<div>count : {count}</div>
</div>
</div>
);
}
const menuInfos = [
{ title: "aaaaaa", children: <Area title="aaaaaa" /> },
{ title: "bbbbbb", children: <Area title="bbbbbb" /> },
{ title: "cccccc", children: <Area title="cccccc" /> },
{ title: "dddddd", children: <Area title="dddddd" /> },
{ title: "eeeeee", children: <Area title="eeeeee" /> }
];
In the current code, the Area component is used within the Menu component, and an instance is created for each menu item. However, when Area component is used across multiple menu items, the count variable is shared, leading to unexpected behavior.
Code sandbox working link : https://codesandbox.io/s/goofy-wind-59v5j9?file=/src/_app.js
I would like to understand reasons about this work and to find a solution to manage the count state eparately for each menu item. I would appreciate any advice on how to modify the code to achieve this.
I have utilized the useEffect hook within the Area component to log the unmount phase using `console.log, and the unmount process appears to be functioning correctly.
Additionally, I compared the children components from the menuInfos array, which are passed as props to the Menu component, using Object.is, and they are recognized as distinct objects.
However, despite these observations, I am struggling to fully comprehend the issue at hand. It seems that I might have overlooked something crucial in my understanding.
>Solution :
React uses a property called key during rendering so it does not update things that do not need updating. If a parent is rendered that has a child for which key is the same as before, then it will do an optimized, reduced kind of rendering which apparently means that updates for {count} are not being done. It’s a different component, but React does not know it.
Adding key properties will make your code work:
const menuInfos = [
{ title: "aaaaaa", children: <Area key="a" title="aaaaaa" /> },
{ title: "bbbbbb", children: <Area key="b" title="bbbbbb" /> },
{ title: "cccccc", children: <Area key="c" title="cccccc" /> },
{ title: "dddddd", children: <Area key="d" title="dddddd" /> },
{ title: "eeeeee", children: <Area key="e" title="eeeeee" /> }
];
