React Router v6,使用Context API进行路由保护的路由

huangapple go评论70阅读模式
英文:

React Router v6, guarded routes using Context API

问题

createBrowserRouter 使用 React Router,可以在此上下文中访问AppContext 信息。你可以通过以下方式来实现在你的场景中访问上下文信息:

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

function ProtectedRoute({ element: Component, ...rest }) {
    const ctx = useContext(AppContext);
    const navigate = useNavigate();
    const location = useLocation();

    if (ctx.token !== "") {
        return <Component {...rest} />;
    } else {
        // Redirect to the login page and preserve the current location state
        navigate('/login', { state: { from: location } });
        return null;
    }
}

通过使用useNavigateuseLocation 钩子,你可以轻松地在用户未登录时将用户重定向到登录页面,并在登录后返回到原来的页面。

英文:

I have the following setup:

App.js

import AppContext from &#39;./context/AppContext.js&#39;;
import router from &#39;./routes/routes.js&#39;;

function App() {
    const [token, setToken] = useState(&quot;&quot;);
    
    function login(token) {
        setToken(token);
    }

    return (
        &lt;React.StrictMode&gt;
            &lt;AppContext.Provider value={{ token, login }}&gt;
                &lt;RouterProvider router={router} /&gt;
            &lt;/AppContext.Provider&gt;
        &lt;/React.StrictMode&gt;
    );
}

export default App;

routes.js

export default createBrowserRouter([
    {
        path: &quot;/&quot;,
        element: &lt;Root /&gt;,
        children: [
            {
                path: &quot;home&quot;,
                element: &lt;Home /&gt;
            },
            {
                path: &quot;admin&quot;,
                element: &lt;ProtectedRoute element={Admin} /&gt;
            },
            {
                path: &quot;login&quot;,
                element: &lt;Login /&gt;
            }
        ]
    }
]);

ProtectedRoute.js

export default function ProtectedRoute({ element: Component, ...rest }) {
    const ctx = useContext(AppContext);

    return (
        ctx.token !== &quot;&quot; ? &lt;Component /&gt; : &lt;Navigate to=&quot;/login&quot; /&gt;
    );
}

I want to be able check if the user is logged in by accessing information from a context, however the returned object always contains the default values. Is there a way to access context information with createBrowserRouter in this scenario?

答案1

得分: 2

The protected route component should be refactored to be rendered as a layout route component by rendering an Outlet instead of some passed prop.

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

export default function ProtectedRoute() {
  const { token } = useContext(AppContext);

  return token
    ? <Outlet />
    : <Navigate to="/login" replace />;
}
export default createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    children: [
      { path: "home", element: <Home /> },
      {
        element: <ProtectedRoute />,
        children: [
          {
            path: "admin",
            element: <Admin />
          },
          // ... other protected routes
        ],
      },
      { path: "login", element: <Login /> }
      // ... other unprotected routes
    ]
  }
]);
英文:

The protected route component should be refactored to be rendered as a layout route component by rendering an Outlet instead of some passed prop.

import { Navigate, Outlet } from &#39;react-router-dom&#39;;

export default function ProtectedRoute() {
  const { token } = useContext(AppContext);

  return token
    ? &lt;Outlet /&gt;
    : &lt;Navigate to=&quot;/login&quot; replace /&gt;;
}
export default createBrowserRouter([
  {
    path: &quot;/&quot;,
    element: &lt;Root /&gt;,
    children: [
      { path: &quot;home&quot;, element: &lt;Home /&gt; },
      {
        element: &lt;ProtectedRoute /&gt;,
        children: [
          {
            path: &quot;admin&quot;,
            element: &lt;Admin /&gt;
          },
          // ... other protected routes
        ],
      },
      { path: &quot;login&quot;, element: &lt;Login /&gt; }
      // ... other unprotected routes
    ]
  }
]);

huangapple
  • 本文由 发表于 2023年4月1日 00:53:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75900946.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定