React调用setState后this.state值未写入更新问题求解
问题描述
在React类组件中定义方法调用setState更新状态时,操作未达到预期,console.log打印的状态值和预期不符,相关代码如下:
editPlan = (cell, row) => { return ( <img src={edit} alt="edit" onClick={() => { console.log(row.id); // 实际打印2,符合预期 this.setState({ editId: row.id, openEditModal: true }); console.log(JSON.stringify(this.state.editId)); // 实际打印空字符串,预期为2 console.log(JSON.stringify(this.state.openEditModal)); // 实际打印false,预期为true this.props.getPlan(row.id); }} /> ); };
问题原因
这是React类组件setState的异步批量更新机制导致的:
- 调用
setState不会立刻同步修改this.state的值,React会将短时间内触发的多个state更新合并,统一触发组件重渲染,减少渲染次数提升性能 - 在调用
setState之后立刻读取this.state时,状态更新流程还未执行,拿到的自然是更新前的旧值
解决方案
根据业务场景选择对应处理方式即可:
- 如果后续逻辑需要依赖更新完成后的state值,给
setState传入第二个参数——状态更新完成后的回调函数,React会在状态更新、组件重渲染完成后执行这个回调,此时读取到的this.state就是最新值,示例写法:
onClick={() => { console.log(row.id); this.setState( { editId: row.id, openEditModal: true }, () => { // 回调内可获取更新后的最新state console.log(JSON.stringify(this.state.editId)); // 打印2 console.log(JSON.stringify(this.state.openEditModal)); // 打印true // 依赖最新state的逻辑写在这里 } ); // 当前代码里的this.props.getPlan(row.id)直接使用入参row.id,不依赖组件自身更新后的state,写在setState外面可以正常执行,不需要放到回调里 this.props.getPlan(row.id); }}
- 如果是通用的状态更新后逻辑,也可以放到类组件的
componentDidUpdate生命周期中执行,监听到对应state变化就触发对应逻辑。
内容的提问来源于stack exchange,提问作者Marty
相关产品推荐
相关产品推荐

