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 };
});
}
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 };
});
}
Share
Improve this question
edited Jun 22, 2019 at 14:58
Sagiv b.g
31k10 gold badges72 silver badges104 bronze badges
asked Jun 22, 2019 at 14:04
rm5432rm5432
3771 gold badge4 silver badges13 bronze badges
3
- 1 The two ways make sense for me and works well, do you get some error? Is this.service.getCustomer(customerCode) returning a Promise? – Jonathas Nascimento Commented Jun 22, 2019 at 14:12
- What is wrong in the first snippet ? – Easwar Commented Jun 22, 2019 at 14:12
- Janathas, I don't think react supports async callback functions in setState(). – rm5432 Commented Jun 22, 2019 at 14:23
2 Answers
Reset to default 3I 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 ment:
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.
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 });
}