首页 > 解决方案 > 反应路由器 useparams 以未定义的形式返回

问题描述

我正在使用 react-router-dom V5。我的代码的一个简单版本是:Index.tsx:

ReactDOM.render(
  <React.StrictMode>
    <Router basename={urlExtra}>
        <App />
    </Router>
  </React.StrictMode>,
  document.getElementById("root")
);

应用程序.tsx

function App() {
  return (
    <>
      <NavBar />
      <main css={content}>
        <Switch>
          <Route exact={true} path={"/"} component={Home} />
          {Routes.map((routes: any) => (
            <Route path={routes.path} key={routes.path} component={routes.component} />
          ))}
          <Route path="*" component={NoMatch} />
        </Switch>
      </main>
    </>
  );
}

导航栏.tsx:

const NavBar: React.FC = () => {
  const { organizationId, tenantId } = useParams();
....

因为我的导航栏在我的路由页面之外,所以它永远不会更新,并且当我切换页面时所有参数都保持为“未定义”。当页面更改更新其中一个值时,我如何告诉导航栏链接更新?

标签: reactjsreact-routerreact-hooksreact-router-dom

解决方案


useParams只能从它包含的路由中提取参数。它本质上是一个钩子的捷径useRouteMatch,使用组合路由数据在组件树中达到一定深度。

您可以通过在任何深度创建自己的路由匹配挂钩实例来手动测试某些路由。例如:

const NavBar: React.FC = () => {
  const match = useRouteMatch({
    path: "/buildings/:organizationId/:tenantId",
    exact: true
  });
}

的值match将是null当路由不匹配时,当它匹配时,它返回一个对象,该对象具有如下所示的属性:

params: {
  organizationId: "someOrganzationId",
  tenantId: "someTenantId"
}

有关更多信息,请查看useRouteMatch的文档和构建它的函数matchPath 。

编辑:

您可以使用更复杂的路径(包括正则表达式)来匹配各种路由语法。在此示例中,路径Test1andTest2将匹配,但不匹配Test3or Tests

function NavBar(){  
  const match = useRouteMatch('/Test:i([1-2])/:id1/:id2');
  
  const { id1, id2 } = {
    id1: match?.params.id1,
    id2: match?.params.id2
  };
  
  return match && (
    <ul>
      <li><Link to={`/Test1/${id1}/${id2}`}>Test 1</Link>
      </li>
      <li><Link to={`/Test2/${id1}/${id2}`}>Test 2</Link>
      </li>
    </ul>
  )
}

推荐阅读