React状态更新延迟一轮迭代,请求调试排查问题
问题根源:React setState的异步特性
你遇到的问题完全是因为React的setState是异步操作导致的,这是React为了性能优化做的设计——它不会在调用setState后立刻更新state,而是会把多个state更新请求批量处理,在合适的时机才会真正更新组件的state和DOM。
你的代码里的问题点
你在调用this.setState()之后立刻执行了console.log(this.state.header.groupByHeader),这时候React还没完成state的更新,所以你打印的还是更新前的旧值(也就是初始的空数组[])。而temporary是你手动创建的本地数组,所以它的值是实时更新的,这就造成了“临时数组更新但state没同步”的错觉。
解决方案:用setState的回调函数获取最新state
React的setState方法支持第二个参数——一个回调函数,这个函数会在state更新完成、组件重新渲染后执行,此时你就能拿到最新的state值了。
修改你的代码如下:
GroupByHandler = (index) => { const temporary = [...this.state.header.groupByHeader]; if(this.state.header.groupByHeader.includes(this.props.Headers[index])) { temporary.splice(index,1); } else { temporary.push(this.props.Headers[index]); } // 把需要查看最新state的逻辑放到setState的回调里 this.setState( { header: { ...this.state.header, groupByHeader: temporary } }, () => { console.log("[PivotTable.js]: 更新后的state"); console.log(this.state.header.groupByHeader); // 这里会打印最新的["advertiser"] console.log("Temporary: "); console.log(temporary); } ); }
额外说明:你的setState写法是正确的
顺便提一句,你更新嵌套state的写法是没问题的:用展开运算符...拷贝了原有的header对象,然后替换groupByHeader属性,没有直接修改原state(直接修改state是React严格禁止的),这部分做得很好。
内容的提问来源于stack exchange,提问作者Shivam Sahil
相关产品推荐
相关产品推荐

