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

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]);

核心逻辑:

  1. 组件挂载或userId变化时,React执行useEffect,创建新的ignore变量并发起请求
  2. 若组件在请求完成前卸载,或userId变化触发新的useEffect,旧的清理函数会将旧作用域的ignore设为true
  3. 当旧请求完成时,它判断的是旧作用域中已变为true的ignore,因此不会执行setTodos,避免过时请求覆盖最新状态
  4. ignore无需作为依赖项,因为它是useEffect内部的局部变量,每个执行周期的作用域相互独立,不会混淆

你的模拟API存入localStorage示例的潜在问题

结合你之前的思路,常见风险包括:

  • 若沿用全局ignore变量,会出现和第一段代码同样的跨实例、跨挂载周期问题
  • 若未处理StrictMode开发环境下的双重渲染逻辑,会发起两次重复请求,虽最终只会存入一次localStorage,但会造成不必要的资源浪费
  • 若未添加类似官方的ignore过时判断,可能出现旧请求结果覆盖新请求的情况,导致localStorage数据不是最新的

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 19:12:28