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

为何我的useEffect(ComponentDidMount)生命周期会触发两次?

问题解决:@preact/signals-react导致React组件useEffect触发两次

问题原因

在React 16.8.6环境下,导入@preact/signals-react的signal后,其内部的响应式转换逻辑会自动对组件进行包装,这种包装逻辑在旧版React中会触发额外的组件初始化流程,导致空依赖的useEffect执行两次。即便你没有实际使用signal,只要导入该模块,转换逻辑就会生效。

解决方案

1. 跳过当前组件的自动转换

在组件定义上方添加注释,让@preact/signals-react不对该组件执行响应式转换:

/* @skipSignals */
const Scenes = (props) => {
    useEffect(() => {
        console.log('ComponentDidMount');
    }, []);

    return <div>Hello</div>;
}

如果后续需要在该组件中使用信号,可以手动调用useSignal或手动订阅信号,不依赖自动转换逻辑。

2. 升级React版本

将React版本升级到17.x或更高,@preact/signals-react对新版React的兼容性更完善,不会出现这类额外触发effect的问题。

3. 配置Babel插件排除特定组件

如果使用了@preact/signals-react的Babel插件,可在配置中添加排除规则,跳过目标组件的转换:

{
  "plugins": [
    ["@preact/signals-react/babel", {
      "exclude": ["src/components/Scenes.js"]
    }]
  ]
}

验证方式

修改后重新运行项目,检查useEffect中的日志是否仅输出一次,确认问题已解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 05:55:08