I have function which dispatched an action. I would like to display a loader before and after the action. I know that react composing the object passed to setState
you can wrap the setState in a Promise and use async/await as below
setStateAsync(state) {
return new Promise((resolve) => {
this.setState(state, resolve)
});
}
async handleChange(input) {
await this.setStateAsync({ load: true });
this.props.actions.getItemsFromThirtParty(input);
await this.setStateAsync({ load: false })
}
Source: ASYNC AWAIT With REACT
Here's what you can do...
onFetchComplete
callback, along with the input
.Change your handleChange to -
handleChange(input) {
this.setState({ load: true }, ()=>
this.props.actions.getItemsFromThirtParty(input,
()=>this.setState({ load: false }))
);
}
This will ensure the action processor code can invoke back your state change callback even if it's not written in a promise based fashion.
A small update- using promises for the action creators and async/await works great, and it makes the code even cleaner, compared to the "then" chaining:
(async () => {
try {
await this.props.actions.async1(this.state.data1);
await this.props.actions.async2(this.state.data2)
this.setState({ load: false );
} catch (e) {
this.setState({load: false, notify: "error"});
}
})();
Of course it is a matter of taste.
EDIT : Added missing bracket
Wrap the rest of your code in the callback of the first setState
:
handleChange(input) {
this.setState({
load: true
}, () => {
this.props.actions.getItemsFromThirtParty(input)
this.setState({ load: false })
})
}
With this, your load
is guaranteed to be set to true
before getItemsFromThirtParty
is called and the load
is set back to false
.
This assumes your getItemsFromThirtParty
function is synchronous. If it isn't, turn it into a promise and then call the final setState
within a chained then()
method:
handleChange(input) {
this.setState({
load: true
}, () => {
this.props.actions.getItemsFromThirtParty(input)
.then(() => {
this.setState({ load: false })
})
})
}
Here's a typescript implementation of an "async-await" setState:
async function setStateAsync<P, S, K extends keyof S>(
component: Component<P, S>,
state:
((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) |
Pick<S, K> |
S |
null
) {
return new Promise(resolve => component.setState(state, resolve));
}