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
相关产品推荐
相关产品推荐

