Javascript React.js,在触发函数之前等待 setState 完成?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37401635/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
React.js, wait for setState to finish before triggering a function?
提问by malexanders
Here's my situation:
这是我的情况:
- on this.handleFormSubmit() I am executing this.setState()
- inside this.handleFormSubmit(), I am calling this.findRoutes(); - which depends on the successful completion of this.setState()
- this.setState(); does not complete before this.findRoutes is called...
- How do I wait for this.setState() inside of this.handleFormSubmit() to finish before calling this.findRoutes()?
- 在 this.handleFormSubmit() 我正在执行 this.setState()
- 在 this.handleFormSubmit() 中,我正在调用 this.findRoutes(); - 这取决于 this.setState() 的成功完成
- this.setState(); 在此之前未完成。findRoutes 被调用...
- 如何在调用 this.findRoutes() 之前等待 this.handleFormSubmit() 中的 this.setState() 完成?
A subpar solution:
一个次要的解决方案:
- putting this.findRoutes() in componentDidUpdate()
- this is not acceptable because there will be more state changes unrelated the findRoutes() function. I don't want to trigger the findRoutes() function when unrelated state is updated.
- 将 this.findRoutes() 放在 componentDidUpdate() 中
- 这是不可接受的,因为会有更多与 findRoutes() 函数无关的状态更改。我不想在更新无关状态时触发 findRoutes() 函数。
Please see code snippet below:
请参阅下面的代码片段:
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>
);
}
});
回答by wintvelt
setState()
has an optional callback parameter that you can use for this. You only need to change your code slightly, to this:
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
);
Notice the call to findRoutes
is now inside the setState()
call,
as the second parameter.
Without ()
because you are passing the function.
注意调用findRoutes
现在在setState()
调用内部,作为第二个参数。
没有()
因为你正在传递函数。
回答by Harshit Singhai
this.setState(
{
originId: input.originId,
destinationId: input.destinationId,
radius: input.radius,
search: input.search
},
function() { console.log("setState completed", this.state) }
)
this might be helpful
这可能会有所帮助
回答by Pawan Samdani
According to the docs of setState()
the new state might not get reflected in the callback function findRoutes()
. Here is the extract from React docs:
根据setState()
新状态的文档可能不会反映在回调函数中findRoutes()
。这是React 文档的摘录:
setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.
There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.
setState() 不会立即改变 this.state 而是创建一个挂起的状态转换。调用此方法后访问 this.state 可能会返回现有值。
无法保证对 setState 调用的同步操作,并且可能会批量调用以提高性能。
So here is what I propose you should do. You should pass the new states input
in the callback function findRoutes()
.
所以这就是我建议你应该做的。您应该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
}
The findRoutes()
function should be defined like this:
该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
}