为何使用Context API在fetch请求中设置state会触发无限请求循环?
问题原因
你遇到的无限循环是典型的状态更新触发组件重渲染,进而重复触发请求的问题:
- 未包裹的fetch请求直接写在Provider组件顶层,每次组件渲染都会执行
- 请求成功后调用
setProfile更新状态,会触发Provider组件重新渲染 - 重渲染后再次执行fetch、更新状态,形成死循环
解决方案
方案1:用useEffect包裹请求(适合动态/需要异步加载的场景)
只需要把fetch逻辑放在useEffect中,设置空依赖数组,保证请求仅在组件首次挂载时执行一次,示例代码如下:
import { createContext, useContext, useState, useEffect } from 'react' // 创建Context const ProfileContext = createContext() // 实现Provider export function ProfileProvider({ children }) { const [profiles, setProfiles] = useState([]) useEffect(() => { const getProfileData = async () => { try { const res = await fetch('/你的本地JSON文件路径.json') const data = await res.json() setProfiles(data) } catch (e) { console.error('数据加载失败:', e) } } getProfileData() }, []) // 空依赖数组,仅执行一次 return ( <ProfileContext.Provider value={{ profiles }}> {children} </ProfileContext.Provider> ) } // 封装自定义调用hook export function useProfiles() { return useContext(ProfileContext) }
方案2:直接导入静态JSON(适合固定不变的本地JSON数据)
如果你的JSON是静态本地文件,可以直接当成模块导入,不需要走fetch请求,写法更简单也不会有异步问题:
import { createContext, useContext, useState } from 'react' // 直接导入本地JSON文件 import profileData from './你的JSON文件路径.json' const ProfileContext = createContext() export function ProfileProvider({ children }) { // 直接用导入的数据初始化状态 const [profiles, setProfiles] = useState(profileData) return ( <ProfileContext.Provider value={{ profiles }}> {children} </ProfileContext.Provider> ) } export function useProfiles() { return useContext(ProfileContext) }
组件调用示例
其他组件要使用数据时,直接调用封装好的useProfiles hook即可,比如下拉框组件:
function NameDropdown() { const { profiles } = useProfiles() return ( <select> {profiles.map(item => ( <option key={item.name} value={item.name}>{item.name}</option> ))} </select> ) }
内容的提问来源于stack exchange,提问作者korpe
相关产品推荐
相关产品推荐

