Réagir.js, attendre que setState finisse avant de déclencher une fonction?
Voici ma situation:
- sur ce.handleFormSubmit () j'exécute ceci.setState ()
- à l'intérieur.handleFormSubmit (), Je l'appelle.trouveritineraires (); qui dépend de la réussite de ce.setState ()
- ceci.setState (); ne se complète pas avant cela.trouveritineraires est appelé...
- Comment puis-je attendre cela?setState() à l'intérieur de cela.handleFormSubmit () à terminer avant l'appel ce.trouveritineraires()?
Un subpar solution:
- mettre cette.trouveritineraires() dans componentDidUpdate()
- ceci n'est pas acceptable car il y aura plus de changements d'état sans rapport avec la fonction findRoutes (). Je ne veux pas déclencher la fonction findRoutes () lorsque l'état non lié est mis à jour.
s'il vous Plaît voir le code ci-dessous l'extrait de code ci-dessous:
handleFormSubmit: function(input){
// Form Input
this.setState({
originId: input.originId,
destinationId: input.destinationId,
radius: input.radius,
search: input.search
})
this.findRoutes();
},
handleMapRender: function(map){
// Intialized Google Map
directionsDisplay = new google.maps.DirectionsRenderer();
directionsService = new google.maps.DirectionsService();
this.setState({map: map});
placesService = new google.maps.places.PlacesService(map);
directionsDisplay.setMap(map);
},
findRoutes: function(){
var me = this;
if (!this.state.originId || !this.state.destinationId) {
alert("findRoutes!");
return;
}
var p1 = new Promise(function(resolve, reject) {
directionsService.route({
origin: {'placeId': me.state.originId},
destination: {'placeId': me.state.destinationId},
travelMode: me.state.travelMode
}, function(response, status){
if (status === google.maps.DirectionsStatus.OK) {
// me.response = response;
directionsDisplay.setDirections(response);
resolve(response);
} else {
window.alert('Directions config failed due to ' + status);
}
});
});
return p1
},
render: function() {
return (
<div className="MapControl">
<h1>Search</h1>
<MapForm
onFormSubmit={this.handleFormSubmit}
map={this.state.map}/>
<GMap
setMapState={this.handleMapRender}
originId= {this.state.originId}
destinationId= {this.state.destinationId}
radius= {this.state.radius}
search= {this.state.search}/>
</div>
);
}
});
3 réponses
setState()
a un paramètre de rappel optionnel que vous pouvez utiliser pour cela. Vous n'avez qu'à changer légèrement votre code, pour ceci:
// Form Input
this.setState(
{
originId: input.originId,
destinationId: input.destinationId,
radius: input.radius,
search: input.search
},
this.findRoutes // here is where you put the callback
);
notez l'appel à findRoutes
est maintenant dans le setState()
appel,
comme deuxième paramètre.
Sans ()
parce que vous passez la fonction.
selon les docs de setState()
le nouvel État pourrait ne pas se refléter dans la fonction de rappel findRoutes()
. Voici l'extrait de Réagir docs:
setState () ne mute pas immédiatement ceci.l'état mais crée une transition d'état en attente. L'accès à ce.l'état après avoir appelé cette méthode peut retourner la valeur existante.
il n'y a aucune garantie de fonctionnement synchrone des appels vers setState et les appels peuvent être groupés pour des gains de performances.
voici donc ce que je vous propose de faire. Vous devriez passer les nouveaux Etats!--4-- > dans la fonction callback findRoutes()
.
handleFormSubmit: function(input){
// Form Input
this.setState({
originId: input.originId,
destinationId: input.destinationId,
radius: input.radius,
search: input.search
});
this.findRoutes(input); // Pass the input here
}
findRoutes()
fonction doit être définie comme ceci:
findRoutes: function(me = this.state) { // This will accept the input if passed otherwise use this.state
if (!me.originId || !me.destinationId) {
alert("findRoutes!");
return;
}
var p1 = new Promise(function(resolve, reject) {
directionsService.route({
origin: {'placeId': me.originId},
destination: {'placeId': me.destinationId},
travelMode: me.travelMode
}, function(response, status){
if (status === google.maps.DirectionsStatus.OK) {
// me.response = response;
directionsDisplay.setDirections(response);
resolve(response);
} else {
window.alert('Directions config failed due to ' + status);
}
});
});
return p1
}
this.setState(
{
originId: input.originId,
destinationId: input.destinationId,
radius: input.radius,
search: input.search
},
function() { console.log("setState completed", this.state) }
)
cela peut être utile