Gutemberg Ribeiro
Gutemberg Ribeiro

Reputation: 1533

Weird behavior on event handlers in React

I wonder if someone can explain the reason of this behavior:

If on a onChange event from an <input> element I have set to point to this method:

private PasswordChanged = (event: any) => {
    this.setState((prevState: IWifiState, props: IWifiProps) => {
        prevState.Password = event.target.value;
        return prevState;
    });
}

This throw me the following error:

Error

Where line 27 is precisely the call to event.target.value on the pasted code.

If I change to code to be like that:

private PasswordChanged = (event: any) => {
    const password = event.target.value;
    this.setState((prevState: IWifiState, props: IWifiProps) => {
        prevState.Password = password;
        return prevState;
    });
}

It just works as expected... Anyone can explain why?

Thanks!

Upvotes: 5

Views: 192

Answers (1)

Elod Szopos
Elod Szopos

Reputation: 3526

React does something called Event Pooling.

What this essentially means is that, for performance considerations, they re-use events.

At the time when you call setState, internally the object might not be okay to re-use as it might behave in ways you wouldn't expect it to (properties get nulled out once the event has served it's purpose).

It is best to save off the reference in a variable for the value that you need, as you did, and use that instead.

Basically, you are accessing it asynchronously (inside the setState function) and it is advised against doing so.

There is a workaround, but I would also advise against it.

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.

Upvotes: 5

Related Questions