[英]How do I make my React state update immediately?
我所做的功能是更新状态的功能并不完美。
我对我修改的当前状态进行了深层复制,然后将状态设置为更改后的副本。 我决定在副本上运行一个简单的映射并更新数组中每个对象的属性,这使应用程序立即更新状态并显示更改。 (未在下面的代码中显示,我刚试过的东西)
但它不适用于我真正想要对副本进行的修改。 由于setState发生异步,我明白这些更改不会立即发生,我该如何解决? 因为第二次触发函数时会看到更改,但我希望它在第一次运行时发生。 如果需要,您可以在https://non.mpedersen.me/上看到我正在构建的实时演示。
App.js中的函数
addressSearch(address){
console.log('firing search for distance. Origin is: ' + address)
let origin = [address];
const newStores = JSON.parse(JSON.stringify(this.state.stores))
let service = new google.maps.DistanceMatrixService();
newStores.map(store => service.getDistanceMatrix({
origins: origin,
destinations: store.addressapi,
travelMode: 'DRIVING',
}, result => {
store.distance = result.rows["0"].elements["0"].distance.text.replace(/\Dkm/, '').replace(/,/,'.').replace(/\s/, '');
store.duration = result.rows["0"].elements["0"].duration.text;
}))
newStores.sort((a,b) => a.distance - b.distance);
this.setState({stores : newStores})
}
在所有getDistanceMatrix
完成并且您的地图完成后,您必须设置setState
。 因为该函数运行异步,所以在setState
时你并没有真正完成函数的完成。 完成发生在另一个堆栈中。
承诺非常好,因为它们有助于处理这样的场景。 这是一个非常好的问题,因为它显示了JS机制(事件循环)的本质。
试试这段代码,但要知道我没有测试/运行它,如果你明白它会把你带到正确的地方:
const getDistanceMatrix = (store) => {
return new Promise((resolve) => {
service.getDistanceMatrix({
origins: origin,
destinations: store.addressapi,
travelMode: 'DRIVING',
}, result => {
store.distance = result.rows["0"].elements["0"].distance.text.replace(/\Dkm/, '').replace(/,/,'.').replace(/\s/, '');
store.duration = result.rows["0"].elements["0"].duration.text;
resolve(store)
})
})
}
addressSearch(address){
console.log('firing search for distance. Origin is: ' + address)
let origin = [address];
const newStores = JSON.parse(JSON.stringify(this.state.stores))
let service = new google.maps.DistanceMatrixService();
Promise.all(newStores.map(getDistanceMatrix).then((newStores) => {
newStores.sort((a,b) => a.distance - b.distance);
this.setState({stores : newStores})
})
}
顺便说一句,在解决Promise之后异步设置状态可能会导致错误,如果主机组件不再安装。 这实际上是采用像redux这样的模式的一个很好的理由,它简化了这样的事情!
这解决了:)
getDistanceMatrix = (address, store) => {
return new Promise((resolve) => {
let service = new google.maps.DistanceMatrixService();
let origin = [address];
service.getDistanceMatrix({
origins: origin,
destinations: store.addressapi,
travelMode: 'DRIVING',
}, result => {
store.distance = result.rows["0"].elements["0"].distance.text.replace(/\Dkm/, '').replace(/,/,'.').replace(/\s/, '');
store.duration = result.rows["0"].elements["0"].duration.text;
resolve(store)
})
})
}
addressSearch(address){
console.log('firing search for distance. Origin is: ' + address)
const newStores = JSON.parse(JSON.stringify(this.state.stores))
Promise.all(newStores.map(store => this.getDistanceMatrix(address, store))).then(newStore => {
newStores.sort((a,b) => a.distance - b.distance);
this.setState({stores : newStores})
})
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.