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>
                );
            }
        });
44
demandé sur Flimzy 2016-05-24 01:35:11

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.

124
répondu wintvelt 2016-05-23 22:45:29

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
}
4
répondu Pawan Samdani 2016-11-22 07:56:43
       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

1
répondu Harshit Singhai 2018-07-06 16:47:26