React StrictMode下避免重复Fetch:代码合规性及原理疑问
回答:React StrictMode下Fetch去重相关问题
你的第一段代码存在严重问题
这段代码里的ignore变量声明在组件外部,属于全局作用域:
let ignore = false; // 全局变量 useEffect(() => { if (ignore) return; fetchStuff().then(res => { setResult(res) }) return () => { ignore = true } }, [])
具体问题:
- 组件第一次卸载时,清理函数会把全局
ignore设为true,之后组件再次挂载时,useEffect会直接跳过fetch,永远无法重新获取数据 - 若存在多个相同组件实例,它们会共享这个全局
ignore,某个组件卸载后,其他实例也无法发起请求
官方示例的去重原理
官方代码里的ignore是声明在useEffect内部的局部变量,每次useEffect执行都会创建独立的作用域:
useEffect(() => { let ignore = false; // 每次useEffect执行都会生成新的局部变量 async function startFetching() { const json = await fetchTodos(userId); if (!ignore) { // 判断当前作用域下的ignore状态 setTodos(json); } } startFetching(); return () => { ignore = true; // 清理函数修改的是当前作用域的ignore }; }, [userId]);
核心逻辑:
- 组件挂载或
userId变化时,React执行useEffect,创建新的ignore变量并发起请求 - 若组件在请求完成前卸载,或
userId变化触发新的useEffect,旧的清理函数会将旧作用域的ignore设为true - 当旧请求完成时,它判断的是旧作用域中已变为
true的ignore,因此不会执行setTodos,避免过时请求覆盖最新状态 ignore无需作为依赖项,因为它是useEffect内部的局部变量,每个执行周期的作用域相互独立,不会混淆
你的模拟API存入localStorage示例的潜在问题
结合你之前的思路,常见风险包括:
- 若沿用全局
ignore变量,会出现和第一段代码同样的跨实例、跨挂载周期问题 - 若未处理StrictMode开发环境下的双重渲染逻辑,会发起两次重复请求,虽最终只会存入一次localStorage,但会造成不必要的资源浪费
- 若未添加类似官方的
ignore过时判断,可能出现旧请求结果覆盖新请求的情况,导致localStorage数据不是最新的
内容的提问来源于stack exchange,提问作者lockedscope
相关产品推荐
相关产品推荐

