165 votes

React.js, attendez setState à terminer avant le déclenchement d'une fonction?

Voici ma situation:

  • sur cette.handleFormSubmit() je suis de l'exécution de cette.setState()
  • à l'intérieur de cela.handleFormSubmit(), je suis à l'appel de cette.trouveritineraires (); qui dépend de la réussite de ce.setState()
  • c'.setState(); ne se termine pas avant cette.trouveritineraires est appelé...
  • Comment dois-je attendre pour cela.setState() à l'intérieur de cela.handleFormSubmit() avant la fin de l'appel de cette.trouveritineraires()?

Un subpar solution:

  • mettre cette.trouveritineraires() dans componentDidUpdate()
  • ce n'est pas acceptable, car il y aura plus de changements d'état sans rapport avec la trouveritineraires() fonction. Je ne veux pas déclencher la trouveritineraires() fonction lorsque indépendants de l'état est mis à jour.

Veuillez 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>
                );
            }
        });

306voto

wintvelt Points 8170

setState() a une option de rappel de paramètres que vous pouvez utiliser pour cela. Vous avez seulement besoin de modifier votre code légèrement, pour cela:

// 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 que l'appel à findRoutes est maintenant à l'intérieur de l' setState()appel, comme deuxième paramètre.
Sans () parce que vous êtes de passage à la fonction.

19voto

Harshit Singhai Points 21
       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

10voto

Pawan Samdani Points 413

Selon les docs de l' setState() le nouvel état ne peut se reflètent dans la fonction de callback findRoutes(). Voici l'extrait de Réagir docs:

setState() ne prend pas immédiatement muter.l'état crée un état d'attente de transition. L'accès à ce.état après l'appel de cette méthode peut peut-être retourner à la valeur existante.

Il n'y a pas de garantie de fonctionnement synchrone des appels à setState et les appels peuvent être groupées pour des gains de performance.

Voici donc ce que je propose, vous devriez le faire. Vous devez passer les nouveaux états - input dans la fonction de 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
}

L' 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
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X