You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复React拼图应用中已卸载组件触发状态更新的报错问题

错误原因

这个报错的本质是组件已经从DOM上卸载后,代码仍然调用了setState尝试更新它的状态。React不会执行这个无效的状态更新,但会抛出该提示,提醒应用存在内存泄漏风险。

你这个场景的触发逻辑是:拼完最后一块拼图时,dropped方法会执行setState({video: true}),触发组件重新渲染后,原先的拼图相关组件(包括你用到的DragDropContainer、DropTarget)都会被卸载,而该拖拽库的onHit回调存在异步触发逻辑,就会出现在组件卸载后仍然尝试调用setState的情况。

修复方法

步骤1:新增组件挂载标记位与生命周期

在Game类中新增挂载标记、componentDidMount和componentWillUnmount生命周期:

export class Game extends Component {
    // 新增挂载标记
    _isMounted = false;

    state = {
        video: false,
    }

    // 新增生命周期:组件挂载后标记为已挂载
    componentDidMount() {
        this._isMounted = true;
    }

    // 新增生命周期:组件卸载前标记为已卸载
    componentWillUnmount() {
        this._isMounted = false;
    }

    // 剩下的原有代码...
}

步骤2:修改setState调用逻辑

修改dropped方法中的setState调用,执行前先判断组件是否还处于挂载状态:

dropped = e => {
    e.containerElem.style.visibility = 'hidden';
    e.target.classList.add('highlighted');
    this.PuzzleCounter++;

    if (this.PuzzleCounter === 3 && this._isMounted) {
        this.setState({
            video :  true,
        });
    }
}
可选优化建议
  • 你目前把styled组件定义为类的实例属性,每次组件实例化都会重新创建样式组件,建议把这些styled组件移到类的外部定义,能提升渲染性能。
  • 后续如果要在视频的onEnded回调中添加修改组件状态的逻辑,同样需要先判断_isMounted标记位,避免出现同类报错。

内容的提问来源于stack exchange,提问作者Thomas Hewitt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 14:09:01