React使用fetch请求时数据丢失或触发无限循环怎么解决?
问题原因分析
- 无限循环根因:你直接把
fetchProfile()写在组件顶层,组件每次渲染都会执行这个函数,函数内调用setServerUser/setData会触发组件重渲染,重渲染又会再次执行fetchProfile(),最终形成无限循环。 - 变量取值异常根因:你混用了
async/await和then写法,res.json()本身返回Promise,你没有await它就直接在外层取值,所以拿到的是Promise对象而非实际接口返回值。另外你函数里的res变量是外层fetch返回的响应对象,then回调里又用了同名的res作为参数,属于变量名冲突,也会干扰取值判断。
修复方案
修改后的完整代码如下:
import { useState, useEffect } from 'react' // 假设user变量是从其他逻辑(比如鉴权hook、上下文)中获取的 const [ serverUser, setServerUser ] = useState('') const [ data, setData ] = useState('') async function fetchProfile(){ try { const res = await fetch( "http://XXX.XXX.XXX.XXX:8080/User/getByEmail", { method: "POST", headers:{"Content-Type":"application/json"}, body:JSON.stringify( { email : user.email } ) } ) // 加await直接获取接口返回的实际数据 const result = await res.json() // 此处直接赋值即可 setServerUser(result) setData(result) console.log(result) } catch (err) { console.error("接口请求失败:", err) } } // 用useEffect包裹请求调用,仅依赖项变化时才触发 useEffect(() => { // 确保邮箱存在时再发请求,避免空参数调用 if(user?.email) { fetchProfile() } // 依赖项仅填写user.email,只有邮箱变化时才重新请求 }, [user.email])
关键修改点说明
- 把
fetchProfile调用放到useEffect中,指定依赖项为user.email,避免组件每次渲染都重复触发请求。 - 统一使用
async/await写法,去掉冗余的then回调,res.json()前加await直接获取实际返回数据,解决Promise取值问题。 - 修改变量名冲突,接口返回数据命名为
result,不和外层响应对象res重名,避免取值混淆。 - 增加
try/catch捕获请求异常,避免接口报错导致页面崩溃。
内容的提问来源于stack exchange,提问作者ABpositive
相关产品推荐
相关产品推荐

