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

React Router v6:登录后重定向至原请求路由问题求助

解决React Router v6登录后重定向到原请求页面的问题

核心思路

拦截未认证请求时,将用户原本要访问的路径存入路由状态(state),登录成功后读取该状态完成重定向。

步骤1:修改ProtectedRoute组件

在拦截跳转时,把当前要访问的路径通过state传递给登录页:

import { Navigate, useLocation } from 'react-router-dom';
import { useAuth } from '../../hooks/useAuth';

export const ProtectedRoute = ({ children }) => {
    const { token } = useAuth();
    const location = useLocation();

    if (!token) {
        // 将原请求路径存入state,传给登录页
        return <Navigate to="/login" state={{ from: location }} />;
    }
    return children;
};

步骤2:修改useAuth的login函数

让login函数接收重定向目标路径参数,登录成功后完成跳转:

import { createContext, useContext, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { useLocalStorage } from './useLocalStorage';
import { authenticateUser } from '../utils/APIFunctions';

const AuthContext = createContext(undefined);

export const AuthProvider = ({ children }) => {
    const [token, setToken] = useLocalStorage('token', null);
    const navigate = useNavigate();

    const login = async (password, redirectTo) => {
        let error = '';
        try {
            const res = await authenticateUser(password);
            if (res?.status === 200 && res?.data[0]?.auth_level > 0) {
                const time = Date.now();
                setToken(password + '-' + time);
                // 登录成功后跳转到原请求路径,或默认路径
                navigate(redirectTo, { replace: true });
            } else {
                if (res.data.name === 'ConnectionError') {
                    error = 'Unable to connect to database.';
                } else if (res?.data?.ReturnValue !== 0) {
                    error = 'Error logging into Scheduler.';
                }
            }
        } catch (err) {
            error = 'Error logging into Scheduler.';
        }
        return error;
    };

    const logout = () => {
        setToken(null);
        navigate('/', { replace: true });
    };

    const value = useMemo(
        () => ({
            token,
            login,
            logout,
        }),
        [token]
    );

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

export const useAuth = () => {
    return useContext(AuthContext);
};

步骤3:在Login组件中传递原路径

从路由状态中取出原请求路径,登录时传给login函数:

import { useLocation } from 'react-router-dom';
import { useAuth } from '../hooks/useAuth';

export const Login = () => {
    const auth = useAuth();
    const location = useLocation();
    // 获取原请求路径,默认值设为你需要的页面(比如'/baglines')
    const from = location.state?.from?.pathname || '/baglines';

    const handleSubmit = async (e) => {
        e.preventDefault();
        const password = e.target.password.value;
        const error = await auth.login(password, from);
        // 处理错误提示,比如渲染error内容
    };

    return (
        <form onSubmit={handleSubmit}>
            <input type="password" name="password" />
            <button type="submit">登录</button>
            {/* 错误提示区域 */}
        </form>
    );
};

补充说明

  • 用await替代.then让异步逻辑更清晰,避免回调嵌套
  • navigate的replace: true选项会替换历史记录,避免用户回退时再次回到登录页
  • 如果用户直接访问登录页,location.state会是undefined,所以要设置默认重定向路径

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 03:58:38