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

React中useEffect触发的fetch请求为何执行两次?

React useEffect 重复执行两次问题解决

问题场景

组件里的useEffect依赖初始值为null的resourceType,原本以为只会执行一次,但页面刷新后控制台里的fetch请求跑了两次。

组件代码

import React, { useState, useEffect } from 'react'

export function UseStateExample() { 
  const [resourceType, setResourceType] = useState(null)

  useEffect(() => {
    fetch(`https://jsonplaceholder.typicode.com/${resourceType}`)
      .then(response => response.json())
      .then(json => console.log(json))
  }, [resourceType])

  // useEffect(() => {
  //   console.log('On Mount, since it is an empty array')
  // }, [])

  return (
    <>
      <div>
        <button onClick={() => setResourceType('posts')}>Posts</button>
        <button onClick={() => setResourceType('users')}>Users</button>
        <button onClick={() => setResourceType('comments')}>Comments</button>
      </div>
      <h1>{resourceType}</h1>
    </>
  )
}

原因

这是React 18+开发环境下**严格模式(Strict Mode)**的特性。Strict Mode会刻意重复执行useEffect、useState初始化这类操作,目的是帮你检测组件里的潜在问题(比如没清理的定时器、订阅)。开发环境下组件挂载时,Strict Mode会先执行一次useEffect,然后模拟卸载再重新挂载,所以你看到两次请求。生产环境下不会有这个重复执行的行为。

另外,初始resourceType为null时,请求的URL是https://jsonplaceholder.typicode.com/null,本身也是个无效请求,没必要发起。

解决办法

1. 跳过无效的初始请求

在useEffect里加个判断,只有当resourceType有有效值时才发起请求:

useEffect(() => {
  if (!resourceType) return; // 初始null时直接返回,不执行fetch
  fetch(`https://jsonplaceholder.typicode.com/${resourceType}`)
    .then(response => response.json())
    .then(json => console.log(json))
}, [resourceType])

2. 开发环境忽略该现象

这只是Strict Mode的调试行为,上线后自动消失,不用特意处理。

3. 关闭Strict Mode(不推荐)

如果实在不想看到重复执行,可以在项目根组件(比如src/index.js)里移除<StrictMode>的包裹,但这样会失去Strict Mode的bug检测能力,不建议这么做。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 05:52:22