From what I learnt about React, you should not mutate any objects otherwise React doesn't know to re-render, for example, the following example should not trigger re-render in the UI when button is clicked on:
import React, { useState } from "react";
import ReactDOM from "react-dom";
function App({ input }) {
const [items, setItems] = useState(input);
return (
<div>
{items.map((item) => (
<MyItem item={item}/>
))}
<button
onClick={() => {
setItems((prevItems) => {
return prevItems.map((item) => {
if (item.id === 2) {
item.name = Math.random();
}
return item;
});
});
}}
>
Update wouldn't work due to shallow copy
</button>
</div>
);
}
function MyItem ({item}) {
const name = item.name
return <p>{name}</p>
}
ReactDOM.render(
<App
input={[
{ name: "apple", id: 1 },
{ name: "banana", id: 2 }
]}
/>,
document.getElementById("container")
);
You can try above code here
And the correct way to update the array of objects should be like below (other ways of deep copying would work too)
setItems((prevItems) => {
return prevItems.map((item) => {
if (item.id === 2) {
# This way we return a deepcopy of item
return {...item, name: Math.random()}
}
return item;
});
});
Why does the 1st version works fine and the UI is updated right away even though I'm just updating the original item object?