React Context获取用户数据时触发无限循环的问题咨询
问题产生原因
- 核心触发点:字段拼写错误
你在useState中定义的登录状态字段为isLoggedIn,但判断逻辑里写的是!value.loggedIn,因为value对象不存在loggedIn属性,取值为undefined,取反后永远为true,导致条件判断持续成立。 - 根本原因:副作用逻辑未做渲染控制
你把用户数据拉取、state修改的逻辑直接写在了组件的顶层渲染流程中,没有用useEffect包裹。每次组件渲染都会执行这段逻辑:- 条件判断成立,调用
updateData({ loading: true })修改state,触发组件重渲染 - 重渲染后条件判断依旧成立,且
fetchUser回调中会把loading改回false,下次判断时!value.loading也成立 - 循环执行「修改state→重渲染→修改state」流程,形成无限循环。
- 条件判断成立,调用
修复方案
- 修正判断条件的拼写错误,将
!value.loggedIn改为!value.isLoggedIn - 把副作用逻辑移到
useEffect中,仅在依赖项变化时执行 - 建议将
setValue改为函数式更新,避免依赖闭包中的旧state
修正后的代码示例
import React, { useState, createContext, useEffect } from "react" import apiRequest from "../axios" import { getCookie } from "../Utils" import jwt_decode from "jwt-decode" export const UserContext = React.createContext() export const UserProvider = (props) => { const [value, setValue] = useState({ loading: false, isLoggedIn: false, userId: "", username: "" }) const updateData = (toUpdate) => { // 函数式更新保证拿到最新的state setValue(prev => ({...prev, ...toUpdate})) } const fetchUser = async (userId, key) => { await apiRequest("get", "/user/" + userId, null, () => {}, (data) => { updateData({ loading: false, isLoggedIn: true, userId: userId, username: data.user.username }) }, (errMessage) => { updateData({ loading: false }) }, key) } // 逻辑移入useEffect,只在依赖项变化时执行 useEffect(() => { const accessToken = getCookie("access") // 修正拼写错误 if (accessToken && !value.isLoggedIn && !value.loading) { updateData({ loading: true }) const { sub: userId } = jwt_decode(accessToken) fetchUser(userId, accessToken) } }, [value.isLoggedIn, value.loading]) const methods = { fetchUser, updateData } return ( <UserContext.Provider value={[value, methods]}> {props.children} </UserContext.Provider> ) }
内容的提问来源于stack exchange,提问作者Bamba675
相关产品推荐
相关产品推荐

