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

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

React Router v6, guarded routes using Context API

问题

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

  1. import { useNavigate, useLocation } from 'react-router-dom';
  2. function ProtectedRoute({ element: Component, ...rest }) {
  3. const ctx = useContext(AppContext);
  4. const navigate = useNavigate();
  5. const location = useLocation();
  6. if (ctx.token !== "") {
  7. return <Component {...rest} />;
  8. } else {
  9. // Redirect to the login page and preserve the current location state
  10. navigate('/login', { state: { from: location } });
  11. return null;
  12. }
  13. }

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

英文:

I have the following setup:

App.js

  1. import AppContext from &#39;./context/AppContext.js&#39;;
  2. import router from &#39;./routes/routes.js&#39;;
  3. function App() {
  4. const [token, setToken] = useState(&quot;&quot;);
  5. function login(token) {
  6. setToken(token);
  7. }
  8. return (
  9. &lt;React.StrictMode&gt;
  10. &lt;AppContext.Provider value={{ token, login }}&gt;
  11. &lt;RouterProvider router={router} /&gt;
  12. &lt;/AppContext.Provider&gt;
  13. &lt;/React.StrictMode&gt;
  14. );
  15. }
  16. export default App;

routes.js

  1. export default createBrowserRouter([
  2. {
  3. path: &quot;/&quot;,
  4. element: &lt;Root /&gt;,
  5. children: [
  6. {
  7. path: &quot;home&quot;,
  8. element: &lt;Home /&gt;
  9. },
  10. {
  11. path: &quot;admin&quot;,
  12. element: &lt;ProtectedRoute element={Admin} /&gt;
  13. },
  14. {
  15. path: &quot;login&quot;,
  16. element: &lt;Login /&gt;
  17. }
  18. ]
  19. }
  20. ]);

ProtectedRoute.js

  1. export default function ProtectedRoute({ element: Component, ...rest }) {
  2. const ctx = useContext(AppContext);
  3. return (
  4. ctx.token !== &quot;&quot; ? &lt;Component /&gt; : &lt;Navigate to=&quot;/login&quot; /&gt;
  5. );
  6. }

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.

  1. import { Navigate, Outlet } from 'react-router-dom';
  2. export default function ProtectedRoute() {
  3. const { token } = useContext(AppContext);
  4. return token
  5. ? <Outlet />
  6. : <Navigate to="/login" replace />;
  7. }
  1. export default createBrowserRouter([
  2. {
  3. path: "/",
  4. element: <Root />,
  5. children: [
  6. { path: "home", element: <Home /> },
  7. {
  8. element: <ProtectedRoute />,
  9. children: [
  10. {
  11. path: "admin",
  12. element: <Admin />
  13. },
  14. // ... other protected routes
  15. ],
  16. },
  17. { path: "login", element: <Login /> }
  18. // ... other unprotected routes
  19. ]
  20. }
  21. ]);
英文:

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

  1. import { Navigate, Outlet } from &#39;react-router-dom&#39;;
  2. export default function ProtectedRoute() {
  3. const { token } = useContext(AppContext);
  4. return token
  5. ? &lt;Outlet /&gt;
  6. : &lt;Navigate to=&quot;/login&quot; replace /&gt;;
  7. }
  1. export default createBrowserRouter([
  2. {
  3. path: &quot;/&quot;,
  4. element: &lt;Root /&gt;,
  5. children: [
  6. { path: &quot;home&quot;, element: &lt;Home /&gt; },
  7. {
  8. element: &lt;ProtectedRoute /&gt;,
  9. children: [
  10. {
  11. path: &quot;admin&quot;,
  12. element: &lt;Admin /&gt;
  13. },
  14. // ... other protected routes
  15. ],
  16. },
  17. { path: &quot;login&quot;, element: &lt;Login /&gt; }
  18. // ... other unprotected routes
  19. ]
  20. }
  21. ]);

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:

确定