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

React中App.js内实现登录成功后重定向至/dashboard的方法

解决登录后重定向到/dashboard的问题

你的核心问题在于:redirect 是React Router专为**路由加载器(loader)或动作函数(action)**设计的API,不能在普通事件回调里直接调用;而<Navigate>组件必须被React渲染到DOM中才会触发跳转,直接在函数里写是无效的。下面给你几种可行的解决方法:

方法1:把登录逻辑移到Login组件内部(推荐)

既然Login组件在Router上下文内部,直接在Login里使用useNavigate是最直接的方式,不用把状态和逻辑都放在App里:

修改Login组件:

import { useState, useNavigate } from 'react';
import axios from 'axios';

function Login() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const navigate = useNavigate();

  const handleEmailChange = (e) => {
    setEmail(e.target.value);
  };

  const handlePasswordChange = (e) => {
    setPassword(e.target.value);
  };

  const handleLogin = async (e) => {
    e.preventDefault();
    try {
      const resp = await axios.post('http://localhost:8000/api/login', { email, password });
      if (resp.status === 200) {
        const { token, refreshToken } = resp.data;
        localStorage.setItem('token', token);
        localStorage.setItem('refreshToken', refreshToken);
        // 直接跳转
        navigate('/dashboard');
      }
    } catch (error) {
      console.error(error);
    }
  };

  return (
    <form onSubmit={handleLogin}>
      {/* 你的输入框和按钮 */}
      <input type="email" value={email} onChange={handleEmailChange} />
      <input type="password" value={password} onChange={handlePasswordChange} />
      <button type="submit">登录</button>
    </form>
  );
}

export default Login;

修改App组件:
去掉多余的状态和回调,简化路由配置:

import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import Login from './Login';
import Signup from './Signup';

function App() {
  const router = createBrowserRouter([
    { path: '/', element: <Signup /> },
    { path: '/login', element: <Login /> },
    { path: '/dashboard', element: <div>Dashboard</div> }
  ]);

  return <RouterProvider router={router} />;
}

export default App;

方法2:通过Router实例的navigate方法跳转

如果你坚持要在App里处理登录逻辑,可以通过createBrowserRouter返回的router实例调用navigate方法:

修改App组件:

import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import Login from './Login';
import Signup from './Signup';
import { useState } from 'react';
import axios from 'axios';

function App() {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  
  // 创建router实例并保存引用
  const router = createBrowserRouter([
    { path: '/', element: <Signup /> },
    { path: '/login', element: <Login 
      handlePasswordChange={(e) => setPassword(e.target.value)}
      handleEmailChange={(e) => setEmail(e.target.value)}
      handleSubmit={handleLogin} 
    /> },
    { path: '/dashboard', element: <div>Dashboard</div> }
  ]);

  const handleLogin = async (e) => {
    e.preventDefault();
    try {
      const resp = await axios.post('http://localhost:8000/api/login', { email, password });
      if (resp.status === 200) {
        const { token, refreshToken } = resp.data;
        localStorage.setItem('token', token);
        localStorage.setItem('refreshToken', refreshToken);
        setIsAuthenticated(true);
        // 使用router实例的navigate方法跳转
        router.navigate('/dashboard');
      }
    } catch (error) {
      console.error(error);
    }
  };

  return <RouterProvider router={router} />;
}

export default App;

方法3:通过状态控制渲染Navigate组件

利用React状态,当登录成功后渲染<Navigate>组件触发跳转:

修改App组件:

import { createBrowserRouter, RouterProvider, Navigate } from 'react-router-dom';
import Login from './Login';
import Signup from './Signup';
import { useState } from 'react';
import axios from 'axios';

function App() {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [shouldRedirect, setShouldRedirect] = useState(false);

  const handleLogin = async (e) => {
    e.preventDefault();
    try {
      const resp = await axios.post('http://localhost:8000/api/login', { email, password });
      if (resp.status === 200) {
        const { token, refreshToken } = resp.data;
        localStorage.setItem('token', token);
        localStorage.setItem('refreshToken', refreshToken);
        setIsAuthenticated(true);
        // 设置重定向状态
        setShouldRedirect(true);
      }
    } catch (error) {
      console.error(error);
    }
  };

  // 如果需要重定向,渲染Navigate组件
  if (shouldRedirect) {
    return <Navigate to="/dashboard" replace />;
  }

  const router = createBrowserRouter([
    { path: '/', element: <Signup /> },
    { path: '/login', element: <Login 
      handlePasswordChange={(e) => setPassword(e.target.value)}
      handleEmailChange={(e) => setEmail(e.target.value)}
      handleSubmit={handleLogin} 
    /> },
    { path: '/dashboard', element: <div>Dashboard</div> }
  ]);

  return <RouterProvider router={router} />;
}

export default App;

注意:方法3需要注意组件重新渲染的时机,确保shouldRedirect状态更新后能触发Navigate的渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:07:46