React Router 6 - 限制访问受保护页面的私人路线组件

373 阅读2分钟

使用React 18.1.0React Router 6.3.0构建的教程

这是一个关于如何用React Router 6实现私有路由组件的快速例子。私有路由组件用于保护React应用中的选定页面不被未经认证的用户访问。

下面的代码片段来自我最近发布的React + Redux JWT认证教程,其中包括一个实时演示,所以要想看到代码运行,请查看React 18 + Redux - JWT认证实例和教程

React Router 6 Private Route

路径。/src/_components/PrivateRoute.jsx

如果用户已经登录,react private route组件会渲染子组件(children )。如果没有登录,用户会被重定向到/login 页面,返回的url在locationstate 属性中传递。

当前登录的用户(authUser)是通过调用useSelector() 钩子从Redux状态中获取的。在这个例子中使用了Redux,但是在React Router 6中实现Private Route组件并不需要它。你可以使用一个不同的状态管理库或任何你喜欢的方法来获取用户的登录状态。

import { Navigate } from 'react-router-dom';
import { useSelector } from 'react-redux';

import { history } from '_helpers';

export { PrivateRoute };

function PrivateRoute({ children }) {
    const { user: authUser } = useSelector(x => x.auth);
    
    if (!authUser) {
        // not logged in so redirect to login page with the return url
        return <Navigate to="/login" state={{ from: history.location }} />
    }

    // authorized so return child components
    return children;
}

带有保护路由的React应用组件

路径。/src/App.jsx

App 组件是示例应用程序的根组件,它包含应用程序的外部html、主导航和路由。

/login 路由是公开的,而主页路由(/)是由私有路由组件保护的,它使用Redux来检查用户是否登录。

最后一个路由是一个全面的重定向路由,将任何不匹配的路径重定向到主页。

import { Routes, Route, Navigate, useNavigate, useLocation } from 'react-router-dom';

import { history } from '_helpers';
import { Nav, PrivateRoute } from '_components';
import { Home } from 'home';
import { Login } from 'login';

export { App };

function App() {
    // init custom history object to allow navigation from 
    // anywhere in the react app (inside or outside components)
    history.navigate = useNavigate();
    history.location = useLocation();

    return (
        <div className="app-container bg-light">
            <Nav />
            <div className="container pt-4 pb-4">
                <Routes>
                <Route
                        path="/"
                        element={
                            <PrivateRoute>
                                <Home />
                            </PrivateRoute>
                        }
                    />
                    <Route path="/login" element={<Login />} />
                    <Route path="*" element={<Navigate to="/" />} />
                </Routes>
            </div>
        </div>
    );
}