React Router v6 useRouteMatch 等效项

Kev*_*gia 16 javascript reactjs react-router react-router-dom

使用 React Router v5 时,可以使用useRouteMatch.

const { path } = useRouteMatch();
Run Code Online (Sandbox Code Playgroud)

React Router v6 提供了类似的钩子,useMatch; 然而,这期望收到您想要匹配的模式。

我将使用 React Router v5 钩子通过将当前路径与已知参数相结合来生成路由。

举个例子,如果我在电子商务应用程序的产品页面上(假设/en/product/:id)并且有相关产品的链接(/en/product/1/en/product/2...等),我以前可以这样做:

const MyComponent = () => {
  const { path } = useRouteMatch();
  return (
    <div>
      <Link to={generatePath(path, { id: 1 })}>Related Product 1</Link>
      <Link to={generatePath(path, { id: 2 })}>Related Product 2</Link>
    </div>
  );
};
Run Code Online (Sandbox Code Playgroud)

由于/en/product来自 API 并且未在代码中的任何位置声明,因此我希望根据当前路径更新 URL。如果用户处于打开状态/es/producto,则链接将自动更新为/es/producto/1

我在 SO 上看到过建议使用 的解决方案matchRoutes,但感觉效率非常低,特别是因为路由是从外部 API 动态生成的。

const useCurrentPath = () => {
  const location = useLocation()
  const [{ route }] = matchRoutes(routes, location)

  return route.path
}
Run Code Online (Sandbox Code Playgroud)

我创建了一个小演示来说明它是如何工作的:

代码沙箱演示

小智 22

在react-router-dom v5中

// Receive the matched url of the current <Route/>
const { url } = useRouteMatch();
Run Code Online (Sandbox Code Playgroud)

在react-router-dom v6中

const url = useResolvedPath("").pathname;
Run Code Online (Sandbox Code Playgroud)

  • React Router API 从一个版本更改到下一个版本的频率真的非常让我烦恼。 (8认同)

Dre*_*ese 4

react-router-dom@6v5 钩子没有替代品useRouteMatch。链接和路由不再需要过多关注模式,path因为它们可以简单地使用相对路由和链接。它可以简单地相对于当前匹配的路径进行导航,而不是尝试访问路线的路径模式。

例子:

这从 导航"/route-a/2""/route-a/2/../1"或更确切地说"/route-a/1"

const { pathname } = useLocation();

// navigate to sibling route path
<Link to={`${pathname}/../${RELATED_ID}`}>
  Go to Nested Route {RELATED_ID}
</Link>
Run Code Online (Sandbox Code Playgroud)

演示

编辑react-router-v6-useroutematch-equivalent

完整代码:

import {
  BrowserRouter,
  Link,
  Route,
  Routes,
  useParams,
  useLocation
} from "react-router-dom";
import "./styles.css";

const RELATED_ID = 1;

const MyComponent = ({ title }) => {
  const { pathname } = useLocation();
  const { id } = useParams();
  return (
    <div>
      <h1>
        {title} {id}
      </h1>
      <pre>{pathname}</pre>
      {id && RELATED_ID && (
        <Link to={`${pathname}/../${RELATED_ID}`}>
          Go to Nested Route {RELATED_ID}
        </Link>
      )}
    </div>
  );
};

export default function App() {
  return (
    <div className="app">
      <BrowserRouter>
        <nav>
          <Link to="/">Home</Link>
          <Link to="/route-a">Route A</Link>
          <Link to="/route-b">Route B</Link>
          <Link to="/route-a/1">Nested Route A1</Link>
          <Link to="/route-a/2">Nested Route A2</Link>
          <Link to="/route-b/1">Nested Route B1</Link>
          <Link to="/route-b/2">Nested Route B2</Link>
        </nav>
        <Routes>
          <Route
            path="/route-b"
            element={<MyComponent title="Nested Route" />}
          />
          <Route
            path="/route-a"
            element={<MyComponent title="Nested Route" />}
          />
          <Route
            path="/route-b/:id"
            element={<MyComponent title="Nested Route" />}
          />
          <Route
            path="/route-a/:id"
            element={<MyComponent title="Nested Route" />}
          />
          <Route path="/" />
        </Routes>
      </BrowserRouter>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)