What\'s the major difference bewteen these two functions?
handleOnChange(evt) {
this.setState(() => ({
tickerName: evt.target.value
}));
}
These are two different syntaxes for setState
First:
handleOnChange(evt) {
this.setState(() => ({
tickerName: evt.target.value
}));
}
uses the updater function as the first argument.
Second:
handleOnChange(evt) {
this.setState({ tickerName: evt.target.value });
}
uses the object to be updated
When using the synthetic event in the updater function you need to use event.persist()
From the documentation:
the SyntheticEvent is pooled. This means that the SyntheticEvent object will be reused and all properties will be nullified after the event callback has been invoked. This is for performance reasons. As such, you cannot access the event in an asynchronous way.
If you want to access the event properties in an asynchronous way, you should call event.persist() on the event, which will remove the synthetic event from the pool and allow references to the event to be retained by user code.
Your fist case would look like
handleOnChange(evt) {
evt.persist();
this.setState(() => ({
tickerName: evt.target.value
}));
}
Or instead of using event.persist()
you could store the event in another object
handleOnChange(evt) {
const value = evt.target.value;
this.setState(() => ({
tickerName: evt.target.value
}));
}
P.S. You should use the updater function for setState only when you wish to update the current state based on prevState
or props
CodeSandbox
React
wraps events in its own SyntheticEvent
which will be reused and all properties will be nullified after the event callback has been invoked
(see react docs).
According to react docs, one can't access react SyntheticEvent
in an asynchronous way and setState
is async. So when setState
is executed your evt
might be null because it gets reused by react
. Since the first function uses a callback with access to previous state in setState
, by the time the callback is executed the event evt
is reused and nullified by react
. In the second case the update object with the event value is created right away and passed in directly and it doesn't create a similar problem.
If you need to use setState
with a callback you need to take care of the event possibly being null when the callback is executed. One way of dealing with this would be store the original reference to target
outside of setState
it will get scoped and used inside setState
. Like this:
handleOnChange(evt) {
const target = evt.target;
this.setState((prevState) => ({
tickerName: target.value
}));
}
I wrote a more detailed answer to why react
events get null in setState
here.