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

React受保护路由致登出后无法跳转Home组件的问题修复

问题修复方案

核心问题分析

登出后地址栏跳转但Grid组件空白,根源是ProtectedRoute组件未响应localStorage中token的变化。原代码里localStorage.getItem('token')仅在组件初始化时执行一次,删除token后组件不会重新渲染,仍返回Grid的路由;但此时Grid因无token加载失败,呈现空白。手动刷新时组件重新初始化,才会检测到token缺失并跳转到Home。

修复步骤

1. 让ProtectedRoute响应token变化

修改ProtectedRoute.js,通过useState和useEffect监听localStorage变化,确保token删除后组件能重新判断权限:

import React, { useState, useEffect } from 'react'
import { Redirect, Route } from 'react-router-dom'

const ProtectedRoute = (props) =>  {
    const [user, setUser] = useState(localStorage.getItem('token'));

    useEffect(() => {
        const handleStorageUpdate = () => {
            setUser(localStorage.getItem('token'));
        };

        window.addEventListener('storage', handleStorageUpdate);
        return () => window.removeEventListener('storage', handleStorageUpdate);
    }, []);

    if(!user) {
        return <Redirect to="/" />;
    }

    return <Route {...props} />;
};

export default ProtectedRoute;

2. 修正Navbar中的代码问题

原Navbar存在useHistory()调用位置错误、token未实时获取的问题,修改如下:

import { useHistory } from "react-router-dom";
import axios from 'axios';

const Navbar = () => {
    const history = useHistory(); // 必须在函数组件内部调用useHistory

    const logout = () => {
        const authToken = localStorage.getItem('token'); // 实时获取当前token
        const headers = {
            "Accept": 'application/json',
            "Authorization": `Bearer ${authToken}`
        };

        axios.post('http://127.0.0.1:8000/api/logout', {}, {headers}) // 传空对象符合接口规范
            .then(resp => {
                localStorage.removeItem('token');
                history.push('/');
            }).catch(err => {
                console.log(err);
            });
    }

    return <Button onClick={logout}>Logout</Button>;
}

export default Navbar;

可选优化:统一管理token状态(推荐)

若项目规模较大,建议在App组件中管理token状态,通过props传递给ProtectedRoute,让路由判断更可靠:

修改App.js:

import { useState, useEffect } from 'react';
import { Router, Switch, Route } from 'react-router-dom';
import ProtectedRoute from './ProtectedRoute';
import Home from './Home';
import Grid from './Grid';

const App = () => {
    const [token, setToken] = useState(localStorage.getItem('token'));

    useEffect(() => {
        const handleStorageChange = () => {
            setToken(localStorage.getItem('token'));
        };

        window.addEventListener('storage', handleStorageChange);
        return () => window.removeEventListener('storage', handleStorageChange);
    }, []);

    return (
        <>
            <Router>
                <Switch>
                    <Route exact path="/" component={Home} />
                    <ProtectedRoute token={token} path="/gallery" component={Grid} />
                </Switch>
            </Router>
        </>
    );
}

export default App;

修改ProtectedRoute.js:

import React from 'react'
import { Redirect, Route } from 'react-router-dom'

const ProtectedRoute = ({ token, ...props }) =>  {
    if(!token) {
        return <Redirect to="/" />;
    }

    return <Route {...props} />;
};

export default ProtectedRoute;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:20:26