如何“包装” <Route> 组件以便它可以在 React 中的 <Router> 内部使用?

abl*_*cz1 3 reactjs react-router

我创建的<RequireAuthRoute>它只是返回其子级或导航到/login. 然而它的使用方式并不令我满意。看看这个片段:

<Route
  path=''
  element={
    <RequireAuthRoute>
      <Explorer />
    </RequireAuthRoute>
  }
/>
Run Code Online (Sandbox Code Playgroud)

所以是的 - 从技术上讲它是有效的,但我想做的是为<Route>组件创建包装器,所以它最终看起来像这样:

<ProtectedRoute path='' element={<Explorer/>}/>
Run Code Online (Sandbox Code Playgroud)

阻碍我的是react-router它本身,它告诉我<Router>直接孩子只能是<Route>组件。有什么解决方法吗?

Dre*_*ese 6

react-router-dom@6自定义路由组件不像 v5 中常用的那样有效。

<ProtectedRoute path='....' element={<Explorer />} />
Run Code Online (Sandbox Code Playgroud)

上面的代码会引发不变违规,因为只有 RouteReact.Fragment是组件的有效子组件Routes,并且Route组件只能由Routes组件或另一个Route组件直接渲染。

如果使用诸如此类的包装组件还RequireAuthRoute不够:

<Route
  path='....'
  element={
    <RequireAuthRoute>
      <Explorer />
    </RequireAuthRoute>
  }
/>
Run Code Online (Sandbox Code Playgroud)

然后,另一个常见的 v6 模式是使用布局路由来渲染Outlet嵌套路由的组件,而不是childrenprop。

例子:

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

const AuthLayout = () => {
  const location = useLocation();
  ... business logic ...

  return isAuthenticated
    ? <Outlet />
    : <Navigate to="/login replace state={{ from: location }} />
};
Run Code Online (Sandbox Code Playgroud)

然后用这个布局路由包装并渲染你想要保护的路由:

<Route element={<AuthLayout />}>
  <Route path='....' element={<Explorer />} />
  ... other protected routes ...
</Route>
... other unprotected routes ...
Run Code Online (Sandbox Code Playgroud)