为什么实现了componentWillUnmount,我的React组件依然没有正常卸载?
问题原因解析
- 你遇到的警告本质是异步回调的时序问题:
componentDidMount中触发的Firebase查询是异步执行的,若查询结果返回前组件已经被卸载,回调中执行的this.setState就会触发“无法给已卸载组件更新状态”的报错。 - 关于
componentWillUnmount没有触发日志的问题,首先检查你写的卸载逻辑里居然调用了this.fetchDo(),这是完全错误的写法,卸载阶段不需要再发起新的异步请求;其次要确认父组件是否真的销毁了当前组件,比如是否做了条件渲染判断、是否开启了路由/组件缓存,只有组件被从渲染树中移除时才会触发卸载生命周期。
修复方案
给组件增加挂载状态标记,异步回调中先判断组件是否处于挂载状态再更新状态,同时修正卸载阶段的逻辑,修复后的代码如下:
constructor(props) { console.log('before'); super(props); this.state = { doctors: '' }; this.fetchDo = this.fetchDo.bind(this); // 新增挂载状态标记 this._isMounted = false; } fetchDo() { firebase .firestore() .collection('Doctors') .get() .then((snapshot) => { let doctorsdata = snapshot.docs.map((doc) => { const data = doc.data(); const id = doc.id; return { id, ...data }; }); // 仅组件挂载时才更新状态 if (this._isMounted) { this.setState({ doctors: doctorsdata, }); } }); } componentDidMount() { this._isMounted = true; this.fetchDo(); console.log('mount'); } componentWillUnmount() { // 标记组件已卸载,终止后续状态更新 this._isMounted = false; console.log('unmount'); }
修复后如果还是没有打印unmount日志,直接排查父组件的渲染逻辑和路由配置,确认组件是否真的会被销毁即可。
内容的提问来源于stack exchange,提问作者Cli Ad
相关产品推荐
相关产品推荐

