React中调用this.setState后函数内部变量值被重置问题求助
问题根本原因
你遇到的问题是React的setState函数式更新参数是异步延迟执行的:
- 你传入setState的计算函数不会在代码执行到setState这行的时候立刻运行,React会攒一批更新操作在合适的时机统一执行,所以setState之后的代码会先运行,此时newPrice还停留在初始赋值的0,自然会拿到错误的值。
解决方案
有两种常用的修复方式,你可以根据场景选择:
方案1:把价格计算逻辑移到setState外部
既然你需要提前拿到计算好的newPrice,直接在调用setState之前同步计算即可,不需要把计算逻辑放到setState的回调里:
addIngredientHandler = (type) => { let oldCount = this.state.ingredients[type]; let copyState = {...this.state.ingredients}; copyState[type] = oldCount + 1; // 同步计算新价格,直接拿到正确值 let newPrice = this.state.totalPrice + PRICES_OF_INGREDIENTS[type]; newPrice = Math.round(newPrice * 100) / 100; this.setState({ ingredients: copyState, totalPrice: newPrice }); console.log('newprice outside setState: ' + newPrice); this.updatePurchaseable(copyState, newPrice); }
该方案逻辑直观性能好,适合绝大多数普通场景。
方案2:把后续逻辑放到setState的完成回调中
如果你的场景存在短时间多次触发更新、可能有pending的state更新,担心直接读this.state拿不到最新值,可以用setState的第二个参数——更新完成后的回调函数,依赖新值的逻辑都放到这个回调里执行:
addIngredientHandler = (type) => { let oldCount = this.state.ingredients[type]; let copyState = {...this.state.ingredients}; copyState[type] = oldCount + 1; let newPrice = 0; this.setState( (prevState, prevProps) => { newPrice = prevState.totalPrice + PRICES_OF_INGREDIENTS[type]; newPrice = Math.round(newPrice * 100) / 100; console.log('newprice inside setState: ' + newPrice); return { ingredients: copyState, totalPrice: newPrice} }, () => { // 此处代码会在state更新完成后执行,newPrice已经完成赋值 console.log('newprice after setState done: ' + newPrice); this.updatePurchaseable(copyState, newPrice); }); }
该方案可以保证拿到的永远是最新的计算结果,适合高频率触发更新的场景。
内容的提问来源于stack exchange,提问作者Shantanu Bedajna
相关产品推荐
相关产品推荐

