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

如何解决React中Login组件auth状态传PrivateRoute时未定义的问题?

问题分析

你当前的核心问题是认证状态auth被定义在Login组件内部,属于局部状态,上层的App组件和PrivateRoutes组件无法访问到这个状态值,所以PrivateRoutes里的auth会是undefined。同时你在PrivateRoutes里的判断逻辑也有问题——直接判断auth对象本身(对象永远为真),而不是判断auth.token的布尔值。

解决办法

下面提供两种常用的修改方案,你可以根据项目复杂度选择:


方案一:状态提升到App组件(适合简单场景)

把auth状态移到更上层的App组件中,再通过props传递给需要的组件:

1. 修改App.jsx

import { useState } from 'react';
import { Routes, Route } from 'react-router-dom';
import PrivateRoutes from './PrivateRoutes';
import MainPage from './MainPage';
import Login from './Login';

function App() {
  // 把auth状态移到App组件中
  const [auth, setAuth] = useState({ token: false });

  return (
    <Routes>
      {/* 把auth传递给PrivateRoutes */}
      <Route element={<PrivateRoutes auth={auth} />}>
        <Route path="/*" element={<MainPage />} />
      </Route>
      {/* 把setAuth传递给Login,用于更新状态 */}
      <Route path="/login" element={<Login setAuth={setAuth} />} />
    </Routes>
  );
}

export default App;

2. 修改Login组件

移除组件内部的auth状态,接收props中的setAuth,同时注意避免函数名和组件名重复:

import { useState } from 'react';

function Login({ setAuth }) {
  const [user, setUser] = useState({ name: '', email: '' });
  const [error, setError] = useState('');

  // 函数名改成handleLogin,避免和组件名冲突
  const handleLogin = (details) => {
    console.log(details);
    if (
      details.name === adminUser.name &&
      details.email === adminUser.email &&
      details.password === adminUser.password
    ) {
      console.log('Logged in');
      setAuth({ token: true });
    } else {
      setError('账号或密码错误');
    }
  };

  // 这里补充你的表单渲染和提交逻辑,比如调用handleLogin
  return (
    // ... 你的表单代码
  );
}

export default Login;

3. 修改PrivateRoutes组件

修正判断逻辑,检查auth.token的布尔值:

import { Outlet, Navigate } from 'react-router-dom';

const PrivateRoutes = ({ auth }) => {
  console.log(auth);
  // 判断auth.token而不是auth对象本身
  return auth.token ? <Outlet/> : <Navigate to="/login"/>;
};

export default PrivateRoutes;

方案二:使用React Context(适合多组件共享状态的复杂场景)

如果你的项目中有多个组件需要用到认证状态,用Context可以避免逐层传递props:

1. 创建AuthContext.jsx

import { createContext, useContext, useState } from 'react';

// 创建Context
const AuthContext = createContext();

// 创建Provider组件,包裹需要共享状态的组件
export function AuthProvider({ children }) {
  const [auth, setAuth] = useState({ token: false });

  return (
    <AuthContext.Provider value={{ auth, setAuth }}>
      {children}
    </AuthContext.Provider>
  );
}

// 自定义Hook,简化Context的使用
export function useAuth() {
  return useContext(AuthContext);
}

2. 修改App.jsx

用AuthProvider包裹整个路由:

import { Routes, Route } from 'react-router-dom';
import { AuthProvider } from './AuthContext';
import PrivateRoutes from './PrivateRoutes';
import MainPage from './MainPage';
import Login from './Login';

function App() {
  return (
    <AuthProvider>
      <Routes>
        <Route element={<PrivateRoutes />}>
          <Route path="/*" element={<MainPage />} />
        </Route>
        <Route path="/login" element={<Login />} />
      </Routes>
    </AuthProvider>
  );
}

export default App;

3. 修改Login组件

通过useAuth获取setAuth:

import { useState } from 'react';
import { useAuth } from './AuthContext';

function Login() {
  const { setAuth } = useAuth();
  const [user, setUser] = useState({ name: '', email: '' });
  const [error, setError] = useState('');

  const handleLogin = (details) => {
    console.log(details);
    if (
      details.name === adminUser.name &&
      details.email === adminUser.email &&
      details.password === adminUser.password
    ) {
      console.log('Logged in');
      setAuth({ token: true });
    } else {
      setError('账号或密码错误');
    }
  };

  // ... 你的表单代码
  return (
    // ...
  );
}

export default Login;

4. 修改PrivateRoutes组件

通过useAuth获取auth状态:

import { Outlet, Navigate } from 'react-router-dom';
import { useAuth } from './AuthContext';

const PrivateRoutes = () => {
  const { auth } = useAuth();
  console.log(auth);
  return auth.token ? <Outlet/> : <Navigate to="/login"/>;
};

export default PrivateRoutes;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:50:31