React Router v6 受保护的路由动态索引页面

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

React Router v6 Protected Routes Dynamic Index Page

问题

我正在尝试创建一个动态的“首页”,如果用户已经认证,那么“/”路由将显示一个仪表板组件,如果他们没有认证,那么“/”路由将显示一个登陆页面;实际上,同一个路径下有两个不同的页面。

如果我在组件本身检查用户是否已经认证,那就足够简单了;但是,我试图使用嵌套路由。

目标是:一组公共路由(例如,“/”,“/login”,“/signup”)和一组私有路由(“/”,“/settings”,“/profile”)-- 这两组路由都嵌套在“/”路由下。

我只是不太确定如何在使用 React Router v6 时实现这一目标。

我的Auth Route父组件非常简单:

import { routeConstants } from '@src/constants';
import { useAuth } from '@src/hooks';
import { Navigate, Outlet } from 'react-router-dom';

const AuthRouter = () => {
  const { user } = useAuth();

  if (!user) {
    return <Navigate to={routeConstants.Routes.LogIn} replace />;
  }

  return <Outlet />;
};

export default AuthRouter;

App.ts:

{/* 私有路由 */}
<Route element={<AuthRouter />}>
  <Route path={RouteConstants.Index} element={<Pages.Home />} />
</Route>

我似乎无法根据认证状态使用嵌套路由来渲染不同的“/”页面。

英文:

I'm trying to create a dynamic "index" page whereby if the user is authenticated, the "/" route shows a dashboard component and if they are not authenticated, the "/" route shows a landing page; effectively having the same path for two different pages.

This is easy enough if I check whether the user is authenticated in the component itself; however, I'm trying to use nested routes.

The goal is: one set of public routes (e.g., "/", "/login", "/signup") and one set of private routes ("/", "/settings", "/profile") -- both of which are nested under the "/" route.

I'm just not sure how to achieve this using react router v6.

My Parent Auth Route is very simple:

import { routeConstants } from &#39;@src/constants&#39;;
import { useAuth } from &#39;@src/hooks&#39;;
import { Navigate, Outlet } from &#39;react-router-dom&#39;;

const AuthRouter = () =&gt; {
  const { user } = useAuth();

  if (!user) {
    return &lt;Navigate to={routeConstants.Routes.LogIn} replace /&gt;;
  }

  return &lt;Outlet /&gt;;
};

export default AuthRouter;

App.ts

      {/* Private Routes */}
      &lt;Route element={&lt;AuthRouter /&gt;}&gt;
        &lt;Route path={RouteConstants.Index} element={&lt;Pages.Home /&gt;} /&gt;
      &lt;/Route&gt;

I just can't seem to render a different "/" page based on auth status using nested routes.

答案1

得分: 1

以下是已翻译的内容:

如果我理解问题正确,您正在询问如何设置一个根主页路由,根据身份验证状态有条件地呈现两个组件中的一个,同时保护多个子路由。为此,您将使用一个专门用于根索引路由的单独布局路由,该路由处理着陆页或仪表板组件的“要么是”条件呈现。AuthRoute 组件将处理保护已验证的路由。

示例:

const AuthRoute = () => {
  const { user } = useAuth();

  if (user === undefined) {
    return null;
  }

  return user
    ? <Outlet />
    : <Navigate to="/login" replace />;
};
const AuthOrUnauth = ({ AuthElement, UnauthElement }) => {
  const { user } = useAuth();

  return user ? AuthElement : UnauthElement;
};
<Routes>
  <Route
    index
    element={(
      <AuthOrUnauth
        AuthElement={<Dashboard />}
        UnauthElement={<Landing />}
      />
    )}
  />
  <Route path="/login" element={<Login />} />
  <Route path="/signup" element={<Register />} />
  <Route element={<AuthRoute />}>
    <Route path="/settings" element={<Settings />} />
    <Route path="/profile" element={<Profile />} />
  </Route>
</Routes>

演示:

React Router v6 受保护的路由动态索引页面

英文:

If I understand the issue correctly you are asking how to have a root home page route that conditionally renders one of two components depending on the auth status while protecting several sub-routes. For this you'll use a separate layout route specifically for the root index route that handles the "either or" conditional rendering of the landing or dashboard components. The AuthRoute component will handle protecting the authenticated routes.

Example:

const AuthRoute = () =&gt; {
  const { user } = useAuth();

  if (user === undefined) {
    return null;
  }

  return user
    ? &lt;Outlet /&gt;
    : &lt;Navigate to=&quot;/login&quot; replace /&gt;;
};
const AuthOrUnauth = ({ AuthElement, UnauthElement }) =&gt; {
  const { user } = useAuth();

  return user ? AuthElement : UnauthElement;
};
&lt;Routes&gt;
  &lt;Route
    index
    element={(
      &lt;AuthOrUnauth
        AuthElement={&lt;Dashboard /&gt;}
        UnauthElement={&lt;Landing /&gt;}
      /&gt;
    )}
  /&gt;
  &lt;Route path=&quot;/login&quot; element={&lt;Login /&gt;} /&gt;
  &lt;Route path=&quot;/signup&quot; element={&lt;Register /&gt;} /&gt;
  &lt;Route element={&lt;AuthRoute /&gt;}&gt;
    &lt;Route path=&quot;/settings&quot; element={&lt;Settings /&gt;} /&gt;
    &lt;Route path=&quot;/profile&quot; element={&lt;Profile /&gt;} /&gt;
  &lt;/Route&gt;
&lt;/Routes&gt;

Demo

React Router v6 受保护的路由动态索引页面

huangapple
  • 本文由 发表于 2023年6月6日 06:16:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76410321.html
匿名

发表评论

匿名网友

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

确定