使用useEffect时如何等待useContext值加载完成以避免重复跳转
问题根因
- 你的代码存在两处基础错误:
useEffect依赖项错误:你声明的上下文变量是user,但依赖数组里写的是users,导致user更新后无法触发useEffect重新执行- 语法错误:
if(user === null缺少右括号,运行时会报错
- 核心逻辑问题:
UserContext的初始user值为null,用户信息是异步拉取的,首次渲染时加载流程还没完成,useEffect就已经执行了跳转判断,直接触发了重定向。
修复方案
第一步:给UserContext补充加载状态
在UserContext的定义逻辑中新增isLoading状态,用来标记用户信息的拉取状态,拉取完成后再把isLoading设为false,示例:
// UserContext.js 示例代码 import { createContext, useState, useEffect } from 'react'; export const UserContext = createContext(); export function UserProvider({ children }) { const [user, setUser] = useState(null); const [isLoading, setIsLoading] = useState(true); // 新增加载状态 useEffect(() => { // 你原来拉取用户信息的逻辑,比如从本地存储/接口取 const fetchUser = async () => { try { const res = await fetch('/api/get-current-user'); const userData = await res.json(); setUser(userData); } catch (err) { setUser(null); } finally { setIsLoading(false); // 拉取完成不管成功失败都标记加载结束 } }; fetchUser(); }, []); return ( <UserContext.Provider value={{ user, isLoading }}> {children} </UserContext.Provider> ); }
第二步:修改UserPage的跳转逻辑
只有加载完成、且用户确实为null的时候才触发跳转,同时修复之前的基础错误:
import React, { useEffect, useContext } from 'react'; import { UserContext } from '../context/UserContext'; export default function UserPage () { const { user, isLoading } = useContext(UserContext); useEffect(() => { // 只有加载结束后,再判断是否需要跳转 if (!isLoading && user === null) { window.location.assign("https://urltoauthenticate:5000/user"); } }, [user, isLoading]); // 修正依赖项 // 加载过程中显示 loading 占位,避免渲染user.name报错 if (isLoading) { return <div>加载中...</div>; } return( <div>Hello {user.name}</div> ) }
额外优化
如果不想修改Context,也可以临时用初始值兜底判断:比如你的user对象正常一定有id或者name字段,就可以判断只有当user是null且页面没有带认证回调的参数时再跳转,但优先推荐加加载状态的方案,逻辑更严谨。
内容的提问来源于stack exchange,提问作者Lalas M
相关产品推荐
相关产品推荐

