禁用Strict Mode后React useEffect仍调用两次的问题求助
问题分析
你遇到的核心问题是:调用setWeekly后触发组件重渲染,进而导致useEffect再次执行——哪怕已经禁用了Strict Mode。主要可能是两个原因:
useEffect的依赖项配置不合理,比如依赖了会被setWeekly修改的weekly状态,或者其他会频繁变化的变量- 当前组件的父组件发生了不必要的重渲染,导致组件被重复渲染,间接触发
useEffect
解决方法
1. 修正useEffect的依赖数组
如果这个useEffect是用来初始化加载用户数据的,依赖数组应该设为空数组([]),这样它只会在组件挂载时执行一次。示例代码:
useEffect(() => { const fetchUserData = async () => { const response = await API.graphql({ query: GET_USER_DATA }); const total = getTotalFromItems(response); setWeekly(total); }; fetchUserData(); }, []); // 空依赖 = 仅组件挂载时执行一次
如果必须依赖某些变量(比如当前登录用户ID),要确保这些变量是稳定的——可以用useMemo或useRef缓存,避免因变量频繁变化触发useEffect。
2. 避免无意义的状态更新
如果getTotalFromItems计算出的新值和当前weekly完全相同,没必要调用setWeekly,可以加个判断跳过:
const fetchUserData = async () => { const response = await API.graphql({ query: GET_USER_DATA }); const newTotal = getTotalFromItems(response); if (newTotal !== weekly) { // 仅当值变化时更新状态 setWeekly(newTotal); } };
这样能避免不必要的组件重渲染,自然也不会触发useEffect重复执行。
3. 优化组件渲染逻辑
检查当前组件的父组件,看看是不是父组件的状态频繁更新导致子组件(也就是你的这个组件)重复渲染。可以给组件套一层React.memo来优化:
const ReceiptScannerComponent = React.memo(() => { // 你的组件逻辑代码 });
React.memo会浅比较组件的props,只有当props真的变化时才会重渲染组件。
4. 手动标记初始化完成(兜底方案)
如果前面的方法都没用,可以用useRef做一个初始化标记,强制useEffect只执行一次:
const isFirstRender = useRef(true); useEffect(() => { if (isFirstRender.current) { const fetchUserData = async () => { const response = await API.graphql({ query: GET_USER_DATA }); setWeekly(getTotalFromItems(response)); }; fetchUserData(); isFirstRender.current = false; } }, []);
这个方法适合排查问题时临时用,优先推荐前面的依赖项修正和状态更新优化方案。
内容的提问来源于stack exchange,提问作者sonny
相关产品推荐
相关产品推荐

