React中_isMounted定义为变量与state有什么区别?
React中_isMounted定义为state与实例变量的行为差异原因
核心根源
二者的更新机制完全不同:React的setState是异步批量执行的,而类实例变量的赋值是同步立即生效的,这是导致表现差异的根本原因。
定义为state时逻辑失效的原因
如果把_isMounted放在state中存储,修改它必须调用setState方法:
state = { _isMounted: false } componentDidMount() { // setState是异步操作,不会立刻更新this.state this.setState({_isMounted: true}) // 如果紧接着在当前事件循环内执行回调,读取this.state._isMounted拿到的还是初始值false // 本该执行的数据填充逻辑会被误判跳过,最终表现为数据无法正常填充 }
setState不会同步修改this.state的值,而是会把更新任务加入队列,等到当前任务流执行完毕、React调度到本次更新时,才会合并state修改并触发组件重渲染。如果你的回调逻辑在setState调用后的同一个事件循环内执行,读取到的永远是更新前的旧值,判断逻辑直接失效。
定义为实例变量时逻辑正常的原因
类实例变量是直接挂载在组件实例上的普通属性,赋值不需要经过React的更新调度,是同步立即生效的:
// 直接声明为实例变量 _isMounted = false state = { /* 其他业务状态 */ } componentDidMount() { // 赋值后立刻生效 this._isMounted = true // 任何位置读取this._isMounted拿到的都是最新值,判断逻辑完全符合预期 }
不需要等待React的更新调度,赋值后立刻就能读取到最新的状态,用来判断是否执行回调的逻辑不会出现时序问题,数据就能正常填充。
额外说明:目前React官方已经不推荐使用
_isMounted模式规避卸载后回调触发的问题,更推荐的做法是在组件卸载时主动取消未完成的请求、清除订阅/定时器,从根源上避免无效回调触发。
内容的提问来源于stack exchange,提问作者John McGellan
相关产品推荐
相关产品推荐

