source

react에서 함수를 트리거하기 전에 setState가 완료될 때까지 어떻게 기다려야 합니까?

nicesource 2023. 3. 5. 09:54
반응형

react에서 함수를 트리거하기 전에 setState가 완료될 때까지 어떻게 기다려야 합니까?

제 상황은 이렇습니다.

  • 이 . handleFormSubmit ( )를 실행합니다.setState()
  • 이 . handle Form Submit ( )내에서는, 이 . find Routes ( ); 를 호출합니다.이것은, 이 처리가 정상적으로 완료되는지에 달려 있습니다.setState()
  • this.setState(); 이 전에 완료되지 않습니다.findRoutes는...
  • 이걸 어떻게 기다리죠?이.handleFormSubmit() 내의 setState()는 이.findRoutes()를 호출하기 전에 완료해야 합니다.

수준 이하의 솔루션:

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

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()call, 두 번째 파라미터로 지정합니다.
없이.()함수 통과 중이기 때문입니다.

여기에 있는 누군가가 착지하여 훅을 사용하여 같은 상황을 겪고 있는 경우, 아래 프로세스를 통해 동일한 동작을 취할 수 있습니다.

const [data, setData] = useState(false);

useEffect(() => {
    doSomething(); // This is be executed when the state changes
}, [data]);

setData(true);

여기서useEffect데이터가 변경되면 실행되며 종속 태스크를 실행할 수 있습니다.

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

setState는, 새로운 스테이트와 옵션의 콜백 함수를 취득합니다.콜백 함수는 스테이트가 갱신된 후에 호출됩니다.

this.setState(
  {newState: 'whatever'},
  () => {/*do something after the state has been updated*/}
)

의 문서에 의하면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()및 그setState()-스위치render()콜시에 양쪽의 실행이 완료되어 있다(처음에는)render()실행) 및/또는 (또는 그 후)render().org docs 입니다.)(ReactJS.org을 참조하십시오.

「 」의 componentDidUpdate()

호출자, 참조 설정 및 상태 설정...

<Cmp ref={(inst) => {this.parent=inst}}>;
this.parent.setState({'data':'hello!'});

부모 렌더링...

componentDidMount() {           // componentDidMount() gets called after first state set
    console.log(this.state.data);   // output: "hello!"
}
componentDidUpdate() {          // componentDidUpdate() gets called after all other states set
    console.log(this.state.data);   // output: "hello!"
}

「 」의 componentDidMount()

호출자, 참조 설정 및 상태 설정...

<Cmp ref={(inst) => {this.parent=inst}}>
this.parent.setState({'data':'hello!'});

부모 렌더링...

render() {              // render() gets called anytime setState() is called
    return (
        <ChildComponent
            state={this.state}
        />
    );
}

다시 후 하십시오.componentDidUpdate().

componentDidMount() {           // componentDidMount() gets called anytime setState()/render() finish
console.log(this.props.state.data); // output: "hello!"
}

언급URL : https://stackoverflow.com/questions/37401635/how-can-i-wait-for-setstate-to-finish-before-triggering-a-function-in-react

반응형