React Router6:将元素传递给私有路由时出现问题

React Router6: issue while passing element to private route

我正在尝试将 PrivateRoute 组件创建为:

import { useStoreState } from 'easy-peasy';
import React, { Component } from 'react';
import { Navigate, Route } from 'react-router-dom';

// import styles from'./index.module.scss';

interface PrivateRouteProps {
  path: string;
  element: Component;
}
const PrivateRoute: React.FC<PrivateRouteProps> = ({
  path,
  element,
  children,
  ...props
}) => {
  const isLoggedIn = useStoreState((state: any) => state.user.isLoggedIn);

  if (!isLoggedIn) {
    return <Navigate to="/login" />;
  }

  return (
    <Route path={path} element={element} {...props}>
      {children}
    </Route>
  );
};
export default PrivateRoute;

这就是我尝试使用它的方式:

function App() {
  return (
    <div className={styles.app}>
      <Router>
        <Routes>
          <Route path="" element={<Home />}></Route>
          <Route path="login" element={<Login />}></Route>
          <PrivateRoute path="cohort" element={MyComponent}></PrivateRoute>
        </Routes>
      </Router>
    </div>
  );
}

但在使用 PrivateRoute 时出现此错误:

我之前 element: React.ComponentType<any> 的尝试解决了 typescript 错误,但新的错误是

Error: [PrivateRoute] is not a component. All component children of must be a <Route> or <React.Fragment>

因此,对于 v6 React 路由器,只有 Route 组件可以是 Routes 的子组件。查看 v6 文档,您会看到身份验证模式是使用包装器组件来处理身份验证检查和重定向。

旧的 v5 模式将不再有效。

这就是您的 PrivateRoute 的样子。我已经注释掉了之前的代码,因此您可以看到我所做的更改。

import { useStoreState } from "easy-peasy";
import React, { Component } from "react";
import { Navigate, Route } from "react-router-dom";

// import styles from'./index.module.scss';

interface PrivateRouteProps {
  path: string;
  element: React.ComponentType<any>;
  // element: Component;
}
// const PrivateRoute: React.FC<PrivateRouteProps> = ({
//   path,
//   element,
//   children,
//   ...props
// }) => {
const PrivateRoute = ({ children }: { children: JSX.Element }) => {
  const isLoggedIn = useStoreState((state: any) => state.user.isLoggedIn);

  if (!isLoggedIn) {
    return <Navigate to="/login" />;
  }

  // return (
  //   <Route path={path} element={element} {...props}>
  //     {children}
  //   </Route>
  // );

  return children;
};

export default PrivateRoute;

然后,您的 App 组件将看起来像这样

export function App() {
  return (
    <div>
      <Router>
        <Routes>
          <Route path="" element={<Home />}></Route>
          <Route path="login" element={<Login />}></Route>
          {/* <PrivateRoute path="cohort" element={MyComponent}></PrivateRoute> */}
          <Route
            path="cohort"
            element={
              <PrivateRoute>
                <MyComponent />
              </PrivateRoute>
            }
          />
        </Routes>
      </Router>
    </div>
  );
}

并且,这里 link 到 codesandbox https://codesandbox.io/s/reactrouterv6wayofdoingthings-0nmkg?file=/src/App.tsx