React.js, 함수를 트리거하기 전에 setState가 완료 될 때까지 기다리시겠습니까?


107

내 상황은 다음과 같습니다.

  • this.handleFormSubmit ()에서 this.setState () 실행 중입니다.
  • this.handleFormSubmit () 내부에서 this.findRoutes (); -this.setState ()의 성공적인 완료에 따라 다릅니다.
  • this.setState (); this.findRoutes가 호출되기 전에 완료되지 않습니다 ...
  • this.findRoutes ()를 호출하기 전에 this.handleFormSubmit () 내부의 this.setState ()가 완료되기를 어떻게 기다리나요?

수준 이하의 솔루션 :

  • componentDidUpdate ()에 this.findRoutes () 넣기
  • findRoutes () 함수와 관련되지 않은 더 많은 상태 변경이 있기 때문에 이것은 허용되지 않습니다. 관련없는 상태가 업데이트 될 때 findRoutes () 함수를 트리거하고 싶지 않습니다.

아래 코드 스 니펫을 참조하십시오.

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

답변:


247

setState()이를 위해 사용할 수있는 선택적 콜백 매개 변수가 있습니다. 다음과 같이 코드를 약간만 변경하면됩니다.

// 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
);

호출 findRoutes은 이제 setState()두 번째 매개 변수로 호출 내부에 있습니다. 함수를 전달하기 때문에
없이 ().


2
놀랄 만한! 대단히 감사합니다
malexanders

이것은 ReactNative에서 setState 후에 AnimatedValue를 재설정하는 데 잘 작동합니다.
SacWebDeveloper

그레이트 ~ 고마워요
吳強福

2
일반 버전this.setState({ name: "myname" }, function() { console.log("setState completed", this.state) })
Sasi Varunan

setState에 둘 이상의 콜백을 전달할 수없는 것 같습니다. 콜백을 연결하는 지저분하지 않은 방법이 있습니까? 실행해야하는 세 가지 메서드와 모든 업데이트 상태가 있다고 가정 해 보겠습니다. 이를 처리하는 데 선호되는 방법은 무엇입니까?
Sean

17
       this.setState(
        {
            originId: input.originId,
            destinationId: input.destinationId,
            radius: input.radius,
            search: input.search
        },
        function() { console.log("setState completed", this.state) }
       )

이것은 도움이 될 것입니다


10

문서에 따르면 setState()새로운 상태는 콜백 함수에 반영되지 않을 수 있습니다 findRoutes(). 다음은 React 문서 에서 발췌 한 것입니다 .

setState ()는 this.state를 즉시 변경하지 않지만 보류 상태 전환을 만듭니다. 이 메서드를 호출 한 후 this.state에 액세스하면 잠재적으로 기존 값을 반환 할 수 있습니다.

setState에 대한 호출의 동기 작업이 보장되지 않으며 성능 향상을 위해 호출이 일괄 처리 될 수 있습니다.

그래서 제가 제안하는 것은 여러분이해야 할 일입니다. input콜백 함수에 새 상태 를 전달해야 합니다 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()기능은 다음과 같이 정의한다 :

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
}

이것은 심각한 결함이 있습니다. setState()새로운 상태로 리터럴 obj를 전달하는 것은 경쟁 조건으로 이어지기 때문에 좋지 않습니다
tar

다음은 반응 문서의 또 다른 인용문입니다 (답변을 게시 한 이후 업데이트되었을 수 있음) : "... use componentDidUpdate 또는 setState 콜백 (setState (updater, callback)), 둘 중 하나는 업데이트 후 실행됩니다. 적용되었습니다 ". 이것은 새로운 상태가 콜백 함수에 가장 확실하게 반영된다는 것을 나에게 말합니다.
Andy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.