J'ai une fonction qui a envoyé une action. Je voudrais afficher un chargeur avant et après l'action. Je sais que réagissent en composant l'objet passé à setState
. la question est de savoir comment puis-je mettre à jour la propriété de manière asynchrone:
handleChange(input) {
this.setState({ load: true })
this.props.actions.getItemsFromThirtParty(input)
this.setState({ load: false })
}
Fondamentalement, tout a fonctionné à merveille si je mettais cette propriété dans l'état de l'application (à l'aide de Redux), mais je préfère vraiment mettre cette propriété dans l'état composant uniquement.
Enveloppez le reste de votre code dans le rappel du premier setState
:
handleChange(input) {
this.setState({
load: true
}, () => {
this.props.actions.getItemsFromThirtParty(input)
this.setState({ load: false })
})
}
Avec cela, il est garanti que votre load
sera défini sur true
avant que getItemsFromThirtParty
ne soit appelé et que le load
ne soit redéfini sur false
.
Cela suppose que votre fonction getItemsFromThirtParty
est synchrone. Si ce n'est pas le cas, transformez-la en une promesse, puis appelez la dernière setState
au sein d'une méthode chaînée then()
:
handleChange(input) {
this.setState({
load: true
}, () => {
this.props.actions.getItemsFromThirtParty(input)
.then(() => {
this.setState({ load: false })
})
})
}
vous pouvez envelopper le setState dans une promesse et utiliser async/wait comme ci-dessous
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
Voici ce que vous pouvez faire ...
onFetchComplete
avec le input
.Changez votre handleChange en -
handleChange(input) {
this.setState({ load: true }, ()=>
this.props.actions.getItemsFromThirtParty(input,
()=>this.setState({ load: false }))
);
}
Cela garantira que le code du processeur d'action peut rappeler votre rappel de changement d'état, même s'il n'est pas écrit de manière promise.
Voici une implémentation TypeScript d'un setState "async-wait":
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));
}
Une petite mise à jour utilisant les promesses pour les créateurs d'action et async/wait fonctionne à merveille et rend le code encore plus propre, comparé au chaînage "d'alors":
(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"});
}
})();
Bien sûr que c'est une question de goût.
EDIT: Ajout du support manquant