React.StrictMode重复触发函数致API报错,是否操作有误?
问题分析与解决方案
首先明确:你遇到的情况不是操作有误,但代码确实存在副作用设计不合理的问题,StrictMode只是把这个潜在问题暴露出来了。
React StrictMode在开发环境下会刻意重复执行以下操作:
- 组件渲染函数
- useEffect、useLayoutEffect的回调函数
- 状态更新函数
- 自定义Hook逻辑
这么做的目的就是帮你发现那些不具备幂等性的副作用——也就是执行多次会导致异常或数据不一致的操作。
你的问题核心在于:cullRecords是一个修改后端数据的写操作,却被绑定在了getData这个读操作里。当StrictMode重复执行getData时,第二次调用cullRecords会试图删除已经被删掉的记录,自然触发API报错。
解决思路
分离读写操作
把cullRecords从getData里拆出来,作为独立的副作用执行,比如单独写一个useEffect:// 单独执行清理操作,比如仅在应用初始化时运行一次 useEffect(() => { async function cleanOldRecords() { await cullRecords(); } cleanOldRecords(); }, []); // 单独获取数据 useEffect(() => { async function fetchData() { const data = await apiCall(); setData(data); } fetchData(); }, []);这样即使StrictMode重复执行,只要
cullRecords逻辑是幂等的(或你控制了执行时机),就不会报错。让cullRecords具备幂等性
如果必须保留当前的绑定关系,要修改cullRecords或对应API:- 在
cullRecords里先检查要删除的记录是否存在,不存在就跳过删除请求 - 让后端API支持重复删除操作,即使记录不存在也返回成功状态(比如204 No Content),而非报错
- 在
开发环境临时处理(不推荐)
如果你只是不想在开发环境看到报错,可以暂时给StrictMode加环境判断,但这只是掩盖问题,不建议长期使用:{process.env.NODE_ENV === 'production' ? ( <React.StrictMode> <App /> </React.StrictMode> ) : ( <App /> )}
总结
StrictMode触发的重复执行不是bug,它是开发环境的调试工具,帮你提前发现生产环境可能出现的问题(比如用户刷新页面导致重复执行副作用)。你的代码问题在于把写操作和读操作耦合在一起,导致非幂等的副作用被重复执行,解决根源问题才是正确做法。
内容的提问来源于stack exchange,提问作者Trees4theForest
相关产品推荐
相关产品推荐

