To add to the other good answers:
In short, you probably want something like this to be safe:
this.setState((prevState) => ({
...prevState, counter: prevState.counter+4
}));
Yes, your current problem was due to the undefined local variable counter
in this statement:
this.setState({ counter: counter+4 });
A simple solution (as pointed out by other answers already) is to refer to the respective state variable:
this.setState({ counter: this.state.counter+4});
As pointed out by cdaiga
, you'd probably want to preserve the other properties on your state since setState()
is replacing the current state with the parameter provided to it and you'd effectively loose all other values on it. You could do it like this:
this.setState({ ...this.state, counter: this.state.counter+4 });
As per the React Documentation, you should also take the asynchronous nature of setState()
into account.
React may batch multiple setState()
calls into a single update for performance.
Because this.props
and this.state
may be updated asynchronously, you should not rely on their values for calculating the next state.
For example, this code may fail to update the counter:
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
To fix it, use a second form of setState()
that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:
// Correct
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
We used an arrow function above, but it also works with regular functions
In your specific example, we would end up with something like this (as already stated at the top):
this.setState((prevState) => ({
...prevState, counter: prevState.counter+4
}));
Additional side note: due to this asynchronous nature of this.setState()
, accessing this.state
after calling this.setState()
will still return its old value. Your original posted code is accessing this.state.counter
immediately afterwards:
this.setState({counter:counter+4}); // error:undefined
for (let i = this.state.counter-4; i < this.state.counter; i++)
arr.push(this.state.arrayHeader[0].content);
}
Fortunately in this case you're not using the variable i
inside the loop and the this.state.arrayheader[0].content
is not being updated, i.e. the following would be equivalent:
this.setState((prevState) => ({
...prevState, counter: prevState.counter+4
}));
for (let i = 0; i < 4; i++) {
arr.push(this.state.arrayHeader[0].content);
}