rm5432
rm5432

Reputation: 377

Async/await in event handler in react

How can I use async/await in an event handler in react?

I understand the following code is wrong because I'm accessing this.state to get the customer code.

<button onClick={handleClick}>Get Customer</button>
async handleClick() {
    let customerCode = this.state.customerCode;
    let customer = await this.service.getCustomer(customerCode);
    this.setState({ customer });
}

Maybe it should be something like this, but I don't think this would work:

handleClick() {
    this.setState(async (prevState) => {
        let customerCode = prevState.customerCode;
        let customer = await this.service.getCustomer(customerCode);
        return { ...prevState, customer };
    }); 
}

Upvotes: 4

Views: 20291

Answers (2)

Jonas Wilms
Jonas Wilms

Reputation: 138397

If the customerCode changes while you are querying, that'll get you into chaos. You could recheck the customerCode before doing the state update:

async handleClick() {
    const { customerCode } = this.state;
    const customer = await this.service.getCustomer(customerCode);

    if(customerCode !== this.state.customerCode)
       return;

    this.setState({ customer });
}

Upvotes: 1

Sagiv b.g
Sagiv b.g

Reputation: 31024

I understand the following code is wrong because I'm accessing this.state to get the customer code

What makes you think it is wrong? It seems legit to me.
If you update a value in state like that (mutation) then it may consider as anti pattern, but reading values that way is perfectly fine.

With that said, i prefer to destruct the properties from the state or any other object in the top of the function's body:

async handleClick() {
  const { customerCode } = this.state;
  let customer = await this.service.getCustomer(customerCode);
  this.setState({ customer });
}

I think it's more readable, but both ways will work fine.

Edit

Just to clarify, when i wrote both ways will work fine, I meant with and without destructuring. e.g the OP first example and my example.

As for this comment:

this.state could be stale

In your case it doesn't matter. The only time an updater argument is required for setState is when the next state is depended on previous state, which is not the case here.

Upvotes: 3

Related Questions