Reputation: 65
I am trying to add a new value to state array but it gives me error.
code
async shouldComponentUpdate(prevProps) {
if (prevProps.navigation.state.params.updated) {
const { updated } = prevProps.navigation.state.params;
// updated = object
const { typeTwo, typeThree } = this.state;
const typeTwoUpdated = await typeTwo.filter((v) => v.id !== updated.id);
const typeThreeUpdated = await typeThree.push(updated);
this.setState({ typeTwo: typeTwoUpdated, typeThree: typeThreeUpdated });
}
}
Error
> [Unhandled promise rejection: TypeError: typeThree.push is not a function. (In 'typeThree.push(updated)', 'typeThree.push' is undefined)]
Edit
Changed the code.
async shouldComponentUpdate(prevProps) {
if (prevProps.navigation.state.params.updated) {
const { updated } = prevProps.navigation.state.params;
// updated = object
const { typeTwo, typeThree } = this.state;
// typeThree = []
const typeTwoUpdated = typeTwo.filter((v) => v.id !== updated.id);
this.setState({ typeTwo: typeTwoUpdated, typeThree: [...typeThree, updated] });
}
}
new error
[Unhandled promise rejection: Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.]
Upvotes: 0
Views: 109
Reputation: 6081
Refer to: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
First of all, Array.prototype.push
is a synchronous operation, it does not need await.
Secondly, it returns the length
of the array when called and mutates the underlying array.
Example
const animals = ['pigs', 'goats', 'sheep'];
const count = animals.push('cows');
console.log(count);
// expected output: 4
console.log(animals);
// expected output: Array ["pigs", "goats", "sheep", "cows"]
You have two ways of doing it:
typeThree.push(updated);
this.setState({ typeTwo: typeTwo.filter((v) => v.id !== updated.id), typeThree });
this.setState({ typeTwo: typeTwo.filter((v) => v.id !== updated.id), typeThree: [...typeThree, updated] });
Upvotes: 0
Reputation: 2104
Try this
async shouldComponentUpdate(prevProps) {
if (prevProps.navigation.state.params.updated) {
const { updated } = prevProps.navigation.state.params;
// updated = object
const { typeTwo, typeThree } = this.state;
// typeThree = []
const typeTwoUpdated = typeTwo.filter((v) => v.id !== updated.id);
this.setState({ typeTwo: typeTwoUpdated, typeThree: [...typeThree, updated });
}
}
Upvotes: 0
Reputation: 1433
Check initial state, particularly state.typeThree.
The shouldComponentUpdate
could be run before you call this.setState({typeThree: Array})
Edit: Please do not add items to an array that is referenced in React component state.
const typeThreeUpdated = typeThree && typeThree.length ? [...typeThree] : [];
typeThreeUpdated.push(updated);
this.setState({ typeTwo: typeTwoUpdated, typeThree: typeThreeUpdated });
Edit 2: So here is what happens
const typeThreeUpdated = await typeThree.push(updated);
this line will result in typeThreeUpdated to be an integer value, which is the new length of typeThree after pushing a new element. The push
mutates the array but returns not the new array, instead it returns the new length. Then it's stored in state as typeThree
in this line
this.setState({ typeTwo: typeTwoUpdated, typeThree: typeThreeUpdated });
and in the next time the function runs, this.state.typeThree is still that number, which has no push function.
Note that you don't need await
here
Upvotes: 1