In my React app I have a page which consists of a list of item cards (each a separated component) and on each of those cards I have a table rendered from item’s nested array objects. When I add an element to the nested array in item by creating a new item with updated array and setting the new list of items as state it does not trigger rerender of the table in the child component.
Here is the rough example of the code I have:
Parent component
const Items = () => {
// Fetching items in useEffect via API call
const [itemsList, setItemsList] = useState([]);
// This method is called in this component to add row to an item,
// but I did not include this part to keep the example concise.
const addRowToItem = (row, itemId) => {
setItemsList(itemsList.map((item) => {
if (item.id === itemId) {
return {...item, rows: item.rows.concat(row)};
}
return item;
}
}
return (
<div>
{itemsList.map((item) => (
<ItemCard item={item} />
)}
</div>
);
}
Child component (ItemCard)
const ItemCard = (props) => {
const [item, setItem] = useState(props.item);
return (
<div>
{item.rows.map((row) => (
// Table row
)}
</div>
);
}
2
Answers
You could either use
useReducer
instead ofuseState
, or clone the state object using the spread operator when assigning the value, like this:Inside Child component (ItemCard):
no need to define
useState
again. you can use the prop directly. remove the second line and:I created a sandbox for, you check it out:
https://codesandbox.io/s/spring-breeze-ykzfln?file=/src/App.js