React Router Dom v6与Typescript

4

我已经升级到react-router-dom v6,之前我使用RouteComponentProps来映射路由,但是现在想知道如何在v6中实现这个功能。

<Switch>
        {routes.map((route, index) => {
            return (
                <Route
                    key={index}
                    exact={route.exact}
                    path={route.path}
                    render={(routeProps: RouteComponentProps<any>) => (
                        <route.component {...routeProps} />
                    )}
                />
            );
        })}
    </Switch>

我知道现在Switch已经被Routes取代,但是不确定什么能够替代RouteComponentProps。

2个回答

3

react-router-dom 6.4 推荐在web应用中使用createBrowserRouter。它使用DOM History API来更新URL并管理历史记录堆栈。

const App = () => {


  const routes = [
    {
      path: "/",
      element: <Dashboard />,
    },
    {
      path: "/messages",
      element: <Messages />,
    },
     {
      path: "/messages/:slug",
      element: <Message />,
    }
  ];

  return <RouterProvider router={createBrowserRouter(routes)} />
};

每个路由可以定义一个加载器函数,通过useLoaderData向根元素提供数据以便渲染。
const AppRoutes = () => {


  const routes = [
    {
      path: "/",
      element: <Dashboard />,
      loader: async () => {
         return fetch(`/api/dashoard`);
      },
    },
    {
      path: "/messages",
      element: <Messages />,
      loader: async () => {
          return fetch(`/api/messages`);
      },
    },
     {
      path: "/messages/:slug",
      element: <Message />,
      loader: async ({param}) => {
          return fetch(`/api/messages/${param.slug}`);
      },
    }
  ];

  return <RouterProvider router={createBrowserRouter(routes)} />
};

const Message = () => {
  const data = useLoaderData()
  return <p> {data.message} </p>

}

你可能还需要使用<Suspanse>。它是一个内置的React组件。

    <Suspense>
      <RouterProvider router={createBrowserRouter(routes, { basename })} />
    </Suspense>

参考资料

  1. https://reactrouter.com/zh-cn/main/routers/create-browser-router

  2. https://reactrouter.com/zh-cn/main/route/loader

  3. https://reactrouter.com/zh-cn/main/hooks/use-loader-data


原始答案

版本6中没有Switch并且已删除render函数。

使用Routes替代Switch

使用element方法替代render方法,它是一个React.ReactNode 类型的参数。

<Routes>
  <Route path="/" element={<Dashboard />} />
  <Route path="messages" element={<DashboardMessages />} />
  <Route path="tasks" element={<DashboardTasks />} />
  <Route path="about" element={<AboutPage />} />
</Routes>;

只有当<route.component />是一个React.ReacNode时,才会执行。

<Routes>
  {routes.map((route, index) => {
    return (
      <Route key={index} path={route.path} element={<route.component />} />
    );
  })}
</Routes>;

Reference:

https://reactrouter.com/docs/en/v6/components/route


0

react-router-dom@6中,路由道具没有替代品。组件应改为使用React Hooks:

请注意,RRDv6中还有其他几个新Hooks。

代码:

<Routes>
  {routes.map((route) => {
    const Component: React.ReactNode | null = route.component;
    return (
      <Route
        key={route.path}
        path={route.path}
        element={<Component />}
      />
    );
  })}
</Routes>

如果路由组件仍然是类组件,则需要将它们转换为函数组件或创建自己的自定义withRouter HOC,因为在v6中也已删除该组件。
例如:
const withRouter = Component => props => {
  const location = useLocation();
  const params = useParams();
  const navigate = useNavigate();

  return <Component {...props} {...{ location, params, navigate }} />;
};

但是如果要在 useLocation 中输入状态,该钩子不接受任何类型参数,那么如何在返回的对象中指定状态/搜索类型呢? - ortonomy
@ortonomy location 对象没有为 location.state 指定类型,或者说它的类型是 unknown。当访问它时,您需要在 您的 代码中将其转换为所需的接口/类型。请参见源代码 - Drew Reese

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接