简体   繁体   English

使用 Params 和 SearchParams 进行 React Router v6 重定向

[英]React Router v6 redirect with Params and SearchParams

I am currently trying to set up my routing for a new project.我目前正在尝试为新项目设置路由。 What I am attempting to implement is if a user access /home/user/settings and they are not logged in, it will redirect them to /login?redirectTo=/home/user/settings .我试图实现的是,如果用户访问/home/user/settings并且他们没有登录,它会将他们重定向到/login?redirectTo=/home/user/settings

Or if they go to /home/device/claim?deviceid=123456789 and they are not logged in they will get redirected to /login?redirectTo=/home/device/claim?deviceid=123456789 .或者,如果他们去/home/device/claim?deviceid=123456789并且他们没有登录,他们将被重定向到/login?redirectTo=/home/device/claim?deviceid=123456789

I currently have it working but I feel it cant be the best way of doing this.我目前正在使用它,但我觉得这不是最好的方法。 An issues I ran into when coming up with this idea were I don't know how many levels the URL will have.我在提出这个想法时遇到的一个问题是我不知道 URL 会有多少级别。

My current code:我当前的代码:

          <Route>
            <Route
              path=":path1/:path2/:path3/:path4"
              element={<RedirectAfterAuth />}
            />
            <Route
              path=":path1/:path2/:path3"
              element={<RedirectAfterAuth />}
            />
            <Route path=":path1/:path2" element={<RedirectAfterAuth />} />
            <Route path=":path1" element={<RedirectAfterAuth />} />
            <Route path="*" element={<Navigate to="/login" />} />
            <Route path="login" element={<Login />} />
            <Route path="/" element={<LandingPage />} />
          </Route>
export default function RedirectAfterAuth() {
  let { path1, path2, path3, path4 } = useParams();
  let [searchParams, setSearchParams] = useSearchParams();
  return (
    <Navigate
      to={`/login?redirectTo=${path1}${path2 ? "/" + path2 : ""}${
        path3 ? "/" + path3 : ""
      }${path4 ? "/" + path4 : ""}${searchParams ? "?" + searchParams : ""}`}
    />
  );
}

I was wondering if there was a way to not have to put loads of different paths and account for all possibilities by just have a single param/searchparam.我想知道是否有一种方法不必放置大量不同的路径并仅通过一个参数/搜索参数来考虑所有可能性。

Thank you for your time感谢您的时间

You don't need to capture all the path segments when redirecting to an authentication route, you can simply capture the current location object and forward that as a "referrer" value for the login component to redirect back.重定向到身份验证路由时,您不需要捕获所有路径段,您可以简单地捕获当前位置对象并将其作为“引荐来源”值转发给登录组件以重定向回来。

Create an authentication layout route component that will be used to protect routes, capture the location, and redirect to the auth route.创建一个身份验证布局路由组件,该组件将用于保护路由、捕获位置并重定向到身份验证路由。

Example:例子:

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

const AuthLayout = () => {
  const location = useLocation(); // <-- current location being accessed
  const { isAuthenticated } = /* auth state from local state/context/redux/etc */

  return isAuthenticated
    ? <Outlet />
    : (
      <Navigate
        to="/login"
        replace                    // <-- redirect
        state={{ from: location }} // <-- forward location
      />
    );
};

export default AuthLayout;

Import and wrap the routes you want to protect with the authentication layout route.使用身份验证布局路由导入并包装要保护的路由。

Example:例子:

import AuthLayout from '../path/to/AuthLayout';

...

<Router>
  {/* Unprotected routes */}
  <Route path="login" element={<Login />} />
  <Route path="/" element={<LandingPage />} />
  ...
  <Route element={<AuthLayout />}>
    {/* Protected routes */}
    <Route path="/profile" element={<Profile />} />
    ...
  </Route>
</Router>

To redirect back to the original route being accessed, the login function accesses the pathname and search ( and any route state ) that was forwarded when getting redirected.为了重定向被访问的原始路由,登录函数访问重定向时转发的pathnamesearch以及任何路由状态)。

Example:例子:

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

...

const navigate = useNavigate();
const location = useLocation();

...

const loginHandler = async e => {
  e.preventDefault();

  try {
    await /* call authentication endpoint/set state/etc */

    // auth success
    const { from } = location.state || {};
    const { pathname, search, state } = from || {};
    navigate(
      (pathname ?? "/") + (search ?? ""),
      {
        replace: true,
        state
      }
    );
  } catch (error) {
  }
};

...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM