You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Context获取用户数据时触发无限循环的问题咨询

问题产生原因

  • 核心触发点:字段拼写错误
    你在useState中定义的登录状态字段为isLoggedIn,但判断逻辑里写的是!value.loggedIn,因为value对象不存在loggedIn属性,取值为undefined,取反后永远为true,导致条件判断持续成立。
  • 根本原因:副作用逻辑未做渲染控制
    你把用户数据拉取、state修改的逻辑直接写在了组件的顶层渲染流程中,没有用useEffect包裹。每次组件渲染都会执行这段逻辑:
    1. 条件判断成立,调用updateData({ loading: true })修改state,触发组件重渲染
    2. 重渲染后条件判断依旧成立,且fetchUser回调中会把loading改回false,下次判断时!value.loading也成立
    3. 循环执行「修改state→重渲染→修改state」流程,形成无限循环。

修复方案

  1. 修正判断条件的拼写错误,将!value.loggedIn改为!value.isLoggedIn
  2. 把副作用逻辑移到useEffect中,仅在依赖项变化时执行
  3. 建议将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 19:45:10