I have a state that is an array of objects
const [objectsArray, setObjectsArray] = useState([
{ name: "first", active: false },
{ name: "second", active: false },
{ name: "third", active: false },
]);
I map this array and render a div for each object
<div>
{objectsArray.map((obj,index) => (
<div className={obj.active ? "active" : "inactive"} key={obj.name}>
{obj.name}
</div>
))}
</div>
As you can see above, the div class is conditionary rendered according to the property 'active'. I want to make an onClick function that toggle the 'active' value between true and false.
I was taught that the correct way of doing it should be this:
const toggler = (objectToBeToggled: number) => {
setObjectsArray((prevState) =>
prevState.map((obj, index) => {
if (index === objectToBeToggled) {
return { ...obj, active: !obj.active };
}
return obj;
})
);
};
<div>
{objectsArray.map((obj, index) => (
<div
className={obj.active ? "active" : "inactive"}
onClick={() => toggler(index)}
key={obj.name}
>
{obj.name}
</div>
))}
</div>
this works completely fine, but as a begginer, the first 2 ideas that cames in my mind was doing the toggler function like this:
first idea that also works
const toggler = (objectToBeToggled: number) => {
let newState = [];
newState = [...objectsArray];
newState[objectToBeToggled].active = !newState[objectToBeToggled].active;
setObjectsArray(newState);
};
or like this:
second idea that doesn't work
const toggler = (objectToBeToggled: number) => {
setObjectsArray((prevState) => {
let newState = [];
newState = [...prevState];
newState[objectToBeToggled].active = !newState[objectToBeToggled].active;
return newState;
});
};
Could someone please explain me why does the second idea is wrong and doesn't work? Why can't I use the same logic as I used in the first idea inside the setter function? And talking about the first idea, is there any problem in directly spreading the state 'objectsArray' to create the let newState ?