I have an array of card component. I will often be adding a card on a user action(like click a button) or the user is able to remove a card. However, since it's useState when the state changes it gets re rendered. But In the case I have 3 cards in my array and that I add a 4th one I really don't want to re render the other 3 when no change happened to them but it's just that they are being in an array made from useState.
The requirement is that it doesn't re render existing component whether I add or remove an element from the array.
I've tried useState & useRef and custom hook and no luck there. With useRef it didn't re render when I needed it to re render. Like it didn't re render the existing but also didn't re render to show the new one. The custom hook combine the add and remove feature but still used useState from within.
Here is a smaller version of the issue in a sandbox. For the sake of a quick example, I'm hardcoding the remove function. In the console, you'll see the console log printing when you add or remove and that's inside the card component(shouldn't happen ideally) https://codesandbox.io/s/no-rerender-array-element-jvu6q5
Thanks for any help!
import "./styles.css";
import React, { useEffect, useRef, useState, useContext } from "react";
const fakeData1 = {
Card1: [1, 2, 3, 4]
};
const fakeData2 = {
Card2: [5, 6, 7, 8]
};
const fakeObject = { fakeData1 };
export default function App() {
const [cardArray, setCardArray] = useState(fakeObject);
const addCard = () => {
setCardArray((entityState) => ({
...entityState,
fakeData2
}));
};
const Card = ({ id, index, item }) => {
console.log("Rendering Card: ", item);
const handleRemove = (event: any | MouseEvent) => {
if (event.type == "click" || event.type == "keydown") {
setCardArray((entityState) => {
const updatedData: any = { ...entityState };
delete updatedData["fakeData2"];
return updatedData;
});
}
};
return (
<div style={{ border: "black solid 2px", padding: "50px 0" }}>
<h1>Card - {id}</h1>
<div>Content: {Object.values(item)}</div>
<button onClick={handleRemove}>Remove</button>
</div>
);
};
return (
<div className="App">
<button onClick={addCard}>Add a Card</button>
{Object.values(cardArray)
.flat()
.map((item: any, index) => {
return <Card id={index} key={index} item={item} />;
})}
</div>
);
}