为何我的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
相关产品推荐
相关产品推荐

