为何基于Vite的这段React代码会向服务器发起两次请求?
为什么你的React代码会发起两次请求?
问题根源
这是React 18开发环境下的**Strict Mode(严格模式)**导致的。Vite默认会在开发环境中启用React Strict Mode,它会刻意重复执行useEffect、组件构造函数等代码,目的是帮你检测未正确清理的副作用(比如未取消的订阅、定时器)。
你的代码里,useEffect依赖是空数组,但判断条件是!posts:
- 第一次执行
useEffect时,posts是初始值null,触发getPosts发起请求; - Strict Mode会模拟组件卸载后重新挂载,此时
posts回到初始的null,第二次执行useEffect时又触发了一次请求,最终导致两次接口调用。
注意:生产环境下Strict Mode会自动禁用,不会出现这个问题。
解决方案
方案1:用状态标记请求是否已发起
添加一个加载状态isLoading,仅在未加载时发起请求,即使useEffect执行两次,第二次时isLoading已变为false,不会重复请求:
import { useEffect, useState } from 'react' import './App.css' import axios from 'axios'; function App() { const [posts, setPosts] = useState(null); const [isLoading, setIsLoading] = useState(true); const getPosts = () => { axios.get('https://tamoudahost.com/wp/wp-json/wp/v2/posts') .then((res) =>{ setPosts(res.data); }) .finally(() => { setIsLoading(false); // 请求完成(成功/失败)都标记为已加载 }) } useEffect(() => { if (isLoading) { getPosts(); } }, [isLoading]) return ( <div className="App"> {posts && posts.map((post) => <div key={post.id}>{post.id} : {post.date}</div>)} </div> ) } export default App
方案2:用useRef标记请求状态
useRef的值在组件重新挂载时不会重置,适合用来标记是否已经发起过请求:
import { useEffect, useState, useRef } from 'react' import './App.css' import axios from 'axios'; function App() { const [posts, setPosts] = useState(null); const hasRequested = useRef(false); useEffect(() => { if (!hasRequested.current) { axios.get('https://tamoudahost.com/wp/wp-json/wp/v2/posts') .then((res) =>{ setPosts(res.data); }); hasRequested.current = true; // 标记为已发起请求 } }, []) return ( <div className="App"> {posts && posts.map((post) => <div key={post.id}>{post.id} : {post.date}</div>)} </div> ) } export default App
方案3:移除Strict Mode(不推荐)
如果你只是想快速消除开发环境的两次请求,可以修改main.jsx(或main.tsx),去掉<React.StrictMode>的包裹:
// 原代码 ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <App /> </React.StrictMode>, ) // 修改后 ReactDOM.createRoot(document.getElementById('root')).render( <App />, )
不推荐这个方案,因为Strict Mode能帮你提前发现很多潜在的代码问题。
内容的提问来源于stack exchange,提问作者salim ben yessef
相关产品推荐
相关产品推荐

