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

React useContext疑问:Login组件可访问变量,Dashboard组件却无法访问?

问题原因及解决方案

核心原因1:状态仅存于内存,页面刷新后丢失

你的LoginProvider用useState存储用户数据,这种状态只存在于内存中。登录成功后如果手动访问/dashboard或刷新页面,React会重新初始化LoginProvider,user会被重置为初始空对象{},导致Dashboard里user.name返回undefined。

核心原因2:Dashboard组件缺少空值安全校验

组件初始渲染时user是空对象,直接访问user.name会触发undefined错误,必须先判断用户数据是否存在再渲染对应内容。

额外问题:登录成功后无自动跳转逻辑

当前Login组件登录成功后没有自动跳转到Dashboard的逻辑,用户手动切换路由时容易出现状态不一致的情况。


具体修复步骤

1. 持久化用户状态到LocalStorage

修改LoginProvider,将用户数据同步到本地存储,初始化时从本地存储读取:

import React, { createContext, useState, useEffect } from "react";
import jwt_decode from 'jwt-decode';

const LoginContext = createContext();

export function LoginProvider({children}) {
    // 初始化时从localStorage读取用户数据
    const [user, setUser] = useState(() => {
        const savedUser = localStorage.getItem('loginUser');
        return savedUser ? JSON.parse(savedUser) : {};
    }) 
    const [isLoggedIn, setIsLoggedIn ] = useState(() => {
        return !!localStorage.getItem('loginUser');
    })

    // 监听user变化,同步到localStorage
    useEffect(() => {
        if (Object.keys(user).length > 0) {
            localStorage.setItem('loginUser', JSON.stringify(user));
        } else {
            localStorage.removeItem('loginUser');
        }
    }, [user]);

    function handleCallbackResponse(response){
        var userData = jwt_decode(response.credential);
        setUser(userData);
        setIsLoggedIn(true);
        document.getElementById('signInDiv').hidden = true;
        // 登录成功后自动跳转到Dashboard
        window.location.href = '/dashboard';
    }

    function handleSignOut(event) {
        setUser({});
        setIsLoggedIn(false); // 补充重置登录状态
        document.getElementById('signInDiv').hidden = false;
        // 退出后跳转到登录页
        window.location.href = '/';
    }  

    return(
        <LoginContext.Provider value={{user, isLoggedIn, handleCallbackResponse, handleSignOut}}>
            {children}
        </LoginContext.Provider>
    );
}

export default LoginContext

2. 给Dashboard组件添加空值保护

修改Dashboard组件,避免直接访问不存在的属性:

import React, { useContext } from 'react'
import Navbar from '../organisms/Navbar'
import './Dashboard.css'
import LoginContext from '../LoginContext'; 

const Dashboard = () => {
  const {user} = useContext(LoginContext) 

  return (
    <div className='dashboard'>
        {/* 可选链+默认值,避免undefined错误 */}
        <h2>{user?.name || '请先登录'}</h2>
        <Navbar/>
        <div className='content'>
            <h1>Welcome to my Dashboard</h1>
        </div>
    </div>
  )
}

export default Dashboard

3. 补充路由守卫(可选)

在App.js中利用isLoggedIn状态做路由拦截,未登录用户无法直接访问Dashboard:

import './App.css';
import { useContext } from 'react';
import Login from './atoms/Login';
import { BrowserRouter , Routes, Route, Navigate } from 'react-router-dom';
import Dashboard from './pages/Dashboard';
import { LoginProvider, LoginContext } from './LoginContext';

// 封装私有路由组件
const PrivateRoute = ({ children }) => {
  const { isLoggedIn } = useContext(LoginContext);
  return isLoggedIn ? children : <Navigate to="/" />;
};

function App() {
  return (
    <LoginProvider >
      <BrowserRouter>
      <Routes>
        <Route path="/dashboard" element={
          <PrivateRoute>
            <Dashboard/>
          </PrivateRoute>
        }/>
        <Route path="/" element={<Login />} />    
      </Routes>
      </BrowserRouter>
    </LoginProvider>
  );
}

export default App;

内容的提问来源于stack exchange,提问作者mateo ghidini

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 03:36:21