This function works properly and the component rerenders
handleRemove = (e) => {
//console.log(e);
const arrayCopy = this.state.scanlist.filter((row) => row.ref + row.lot !== e.ref + e.lot);
this.setState({ scanlist: arrayCopy });};
This function changes the state but the component does not rerender
handleAdd = (e) => {
//console.log(e);
const index = this.state.scanlist.findIndex((row) => row.ref === e.ref && row.lot === e.lot);
let scancopy = this.state.scanlist;
scancopy[index].qty = scancopy[index].qty + 1;
console.log(scancopy);
this.setState({ scanlist: scancopy });};
Does anyone see the issue? Mutation?
Using Array.prototype.filter
to remove an element from an array is pretty standard, but in the second handler yes, you've a state object mutation.
handleAdd = (e) => {
const index = this.state.scanlist.findIndex((row) => row.ref === e.ref && row.lot === e.lot);
let scancopy = this.state.scanlist;
scancopy[index].qty = scancopy[index].qty + 1; // <-- state object mutation
this.setState({ scanlist: scancopy });
};
You should shallow copy the scanlist
array and the element that is being updated. Array.prototype.map
is a common method to shallow copy the state array, and spreading the object properties of the element that needs to be updated shallow copies it. Anytime you are updating any nested state objects you should shallow copy the parent object.
handleAdd = (e) => {
this.setState(prevState => ({
scanlist: prevState.scanlist.map(
(row) => row.ref === e.ref && row.lot === e.lot ? {
...row,
qty: row.qty + 1,
} : row)
}));
};