【问题标题】:react-router-dom get id from route with custom components and extra pathreact-router-dom 从带有自定义组件和额外路径的路由中获取 id
【发布时间】:2020-03-14 09:42:04
【问题描述】:

我有一个应用程序使用 react-router-config 并使用 wrapper component 重定向未经身份验证的用户。

我有一些需要使用路由 /tasks/:id 的功能,但我无法访问 :id 值来执行必要的任务查找。

我的 routes.js:

import React from "react";
...
const Tasks = React.lazy(() => import("./Components/Tasks"));
...
const routes = [
  {
    path: "/tasks/edit/:id",
    name: "View Task",
    component: Tasks
  }
...
];
export default routes;

那我有AuthenticatedRoute.js:

import React from "react";
import { Route, Redirect } from "react-router-dom";

export default function AuthenticatedRoute({
  component: C,
  appProps,
  ...rest
}) {
  return (
    <Route
      {...rest}
      render={props =>
        appProps.isAuthenticated ? (
          <C {...props} {...appProps} />
        ) : (
          <Redirect
            to={`/login?redirect=${props.location.pathname}${props.location.search}`}
          />
        )
      }
    />
  );
}

在 App.js 中:

import React, { useState, useEffect } from "react";
import { BrowserRouter, Switch, withRouter } from "react-router-dom";
import AuthenticatedRoute from "./components/AuthenticatedRoute/AuthenticatedRoute";
import routes from "./routes";

function App(props) {
...
  return (
    <BrowserRouter>
      <React.Suspense fallback={loading()}>
        <Switch>
            {routes.map((route, idx) => {
              return route.component ? (
                <AuthenticatedRoute
                  key={idx}
                  path={route.path}
                  exact={route.exact}
                  name={route.name}
                  appProps={props}
                  component={props => <route.component {...props} />}
                />
              ) : null;
            })}
        </Switch>
...
      </React.Suspense>
    </BrowserRouter>

终于有了我的 Tasks.js:

import React, { useState, useEffect } from "react";
...
function Tasks(props) {
  useEffect(() => {
    onLoad();
  }, []);

  const onLoad = async () => {
    console.log(JSON.stringify(props.match.params));
  };
...

浏览到 localhost:3000/tasks/1。 props.match.params 在链上的每个组件中都是空的。 props.match.params.idundefined。我也尝试过匹配{match.params.id},但这在每个组件中也是未定义的。

我可以看到props.location.pathname,但这是完整路径,我必须手动获取最后一段。我无法让它自动从网址中获取:id

编辑 原来我的例子太简单了,这实际上帮助我发现了问题。在我之前的版本中,当我有路线时:

  {
    path: "/tasks/:id",
    name: "View Task",
    component: Tasks
  }

使用useParams 实际上一切正常我能够获得:id 值。我在我的应用程序中实际拥有的以及似乎正在破坏它的是在路径中添加了一个额外的目录:

  {
    path: "/tasks/edit/:id",
    name: "View Task",
    component: Tasks
  }

我不确定这有何不同,但拥有额外的 /edit 似乎会破坏 useParams

【问题讨论】:

  • 尝试使用const { id } = useParams();。从 react-router-dom 导入 useParams。
  • 你能提供一个codeandbox之类的吗?
  • 在创建代码框时,我想我发现了问题所在。我的路线有一条额外的路径,似乎正在破坏它。

标签: reactjs react-router-dom


【解决方案1】:

react-router-dom 提供了一些方便的钩子。在你的情况下,我建议useParams()(链接到文档)

import { useParams } from 'react-router-dom';

function MyComponent {
  let { id } = useParams();

  return (<p>{id}</p>);
}

如果你将使用 React Router 提供的钩子,我也可能会选择不使用 withRouter

【讨论】:

  • 谢谢。我更新了我的问题。我在我的应用程序中创建了一个新页面,只有一个基本路径 /test/:id 并且您的代码有效。当我添加额外的目录(这是我的应用程序实际拥有的)/test/edit/:id 它不再有效。
  • Check out this sandbox: let { id } = useParams() 应该工作
  • 我的路径是/student/general/request/:id。我可以得到身份证,但我需要检查它是否是通用的。有什么方法可以捕获路径的一般部分?
  • @Ravisara 你可以使用useLocation()
  • 谢谢。使用我的代码可以使用“let { id, type } = useParams()”
【解决方案2】:

Martins 的答案是正确的,适用于功能组件。 我遇到了同样的问题,但是我使用了一个类组件(类 Company 扩展了组件),而 Martins 的回答不适用于这种情况。 如果你有一个类组件,你可以这样做:

import { withRouter } from 'react-router-dom'

class MyComponent extends React.Component {

    componentDidMount() {
        // here you have the id
        const id = this.props.match.params.id;
      }

}

export default withRouter(MyComponent);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    相关资源
    最近更新 更多