React Router hooks 将使你的组件更简洁

2025-06-04

React Router hooks 将使你的组件更简洁

作者:Nathan Sebhastian✏️

React Router 是一个轻量级库,允许您管理和处理 React 应用程序的路由。

React Router 最突出的特性之一是路由渲染方法,它使你的组件能够访问matchlocationhistory属性。这些属性一起用于将数据从 URL 传递到组件,并以编程方式导航你的 React 应用程序。

例如,如果你想创建一个返回按钮,你可以使用propsgoBack()中的函数history。这抽象了不同环境或浏览器之间的差异,让你可以用一个简单的函数返回上一个网页。

// a Route with component props
<Route path="/post/:number" component={Post} />

// The component itself
function Post(props) {
  return (
    <div>
      In React Router v4, you get the history object from props. <br />
      <button type="button" onClick={() => props.history.goBack()}>
        Go back
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

虽然这工作正常,但路由的渲染方法被普遍认为难以阅读,而且非常奇怪。因此,从5.1 版本开始,React Router 将包含四个实用的钩子,你可以使用它们来编写简洁、整齐堆叠、赏心悦目的导航组件。我将通过与版本 4 中的旧模式进行比较,向你展示这些新钩子的工作原理。

我们将从钩子开始useParams

LogRocket 免费试用横幅

UseParams

useParams钩子将从您的应用程序 URL 返回一个设置为动态的键值对对象。在复杂的应用程序中,通常会有许多动态的导航链接。

例如,你可能有一个/post/:idURL,它会向应用程序的后端发起一个获取过程。在这种情况下,最常见的 React Router 模式是使用组件 prop。

export default function App() {
  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/post/hello-world">First Post</Link>
            </li>
          </ul>
        </nav>
        <Switch>
          <Route path="/post/:slug" component={Post} />
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}
Enter fullscreen mode Exit fullscreen mode

通过将Post组件传递到组件中/post/:number Route,您可以从 React Router 传递到组件中的 propparams中提取对象matchPost

// Old way to fetch parameters
function Post({ match }) {
  let params = match.params;
  return (
    <div>
      In React Router v4, you get parameters from the props. Current parameter
      is <strong>{params.slug}</strong>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

这种方法效果很好,但如果你的应用程序很大,包含大量动态路由,那么这种方法就相当繁琐了。你必须跟踪哪些Route组件需要组件 props,哪些不需要。此外,由于match对象是从渲染组件传递Route到渲染组件的,你需要将它们传递给 DOM 树中更下游的组件。

这就是 hook 真正闪耀的地方useParams。它是一个简洁的辅助函数,可以为你提供当前路由的参数,这样你就不必使用组件 props 模式了。

<Switch>
  <Route path="/post/:slug" component={Post} />
  <Route path="/users/:id/:hash">
    <Users />
  </Route>
  <Route path="/">
    <Home />
  </Route>
</Switch>

function Users() {
  let params = useParams();
  return (
    <div>
      In React Router v5, You can use hooks to get parameters.
      <br />
      Current id parameter is <strong>{params.id}</strong>
      <br />
      Current hash parameter is <strong>{params.hash}</strong>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

如果子组件Users需要访问参数,您useParams()也可以简单地在那里调用。

如果您想看看它的实际效果,这里有一个例子。

UseLocation

在 React Router 版本 4 中,就像获取参数一样,您必须使用组件 props 模式来访问location对象。

<Route path="/post/:number" component={Post} />

function Post(props) {
  return (
    <div>
      In React Router v4, you get the location object from props. <br />
      Current pathname: <strong>{props.location.pathname}</strong>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

在 5.1 版本中,您可以调用钩子从 React RouteruseLocation获取对象。location

<Route path="/users/:id/:password">
  <Users />
</Route>

// new way to fetch location with hooks
function Users() {
  let location = useLocation();
  return (
    <div>
      In React Router v5, You can use hooks to get location object.
      <br />
      Current pathname: <strong>{location.pathname}</strong>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

再次,您可以在CodeSandbox上看到示例代码

UseHistory

这让我们少了一个使用组件 props 的理由。但是,你仍然需要使用组件或渲染模式来获取history对象吗?

对象history是您需要使用组件或渲染道具模式的最后一个原因。

<Route path="/post/:slug" component={Post} />

// Old way to fetch history
function Post(props) {
  return (
    <div>
      In React Router v4, you get the history object from props. <br />
      <button type="button" onClick={() => props.history.goBack()}>
        Go back
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

通过使用useHistory钩子,您可以获得相同的历史对象,而无需Route组件将其传递下去。

<Route path="/users/:id/:hash">
  <Users />
</Route>

// new way to fetch history with hooks
function Users() {
  let history = useHistory();
  return (
    <div>
      In React Router v5, You can use hooks to get history object.
      <br />
      <button type="button" onClick={() => history.goBack()}>
        Go back
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

请参阅此示例代码useHistory以了解与常规道具之间的比较history

component现在,您可以拥有一个简洁的路由组件,无需任何使用props的奇怪组件组合render。您只需放置一个<Route>带有 props 的组件path,并将渲染的children组件放入其中即可。

useRouteMatch

有时,您只需要使用<Route>组件来访问match对象。

<Route path="/post">
  <Post />
</Route>

function Post() {
  return (
    <Route
      path="/post/:slug"
      render={({ match }) => {
        return (
          <div>
            Your current path: <strong>{match.path}</strong>
          </div>
        );
      }}
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

上面的示例展示了一种match不使用componentrenderprops 来访问对象的方法。在最新版本的 React Router 中,你还可以使用useRouteMatch钩子,它使你能够抓取match对象并在组件内部使用它,而无需使用<Route>

<Route path="/users">
  <Users />
</Route>

// useRouteMatch to make your route above cleaner
function Users() {
  let match = useRouteMatch("/users/:id/:hash");
  return (
    <div>
      In React Router v5, You can use useRouteMatch to get match object. <br /> Current match path: <strong>{match.path}</strong> </div> ); }
Enter fullscreen mode Exit fullscreen mode

现在,你无需创建<Route>组件来抓取match对象了。这里有另一个示例供你参考。

结论

React Router 团队利用钩子的强大功能并实现它来跨组件共享逻辑,而无需从树的顶部向下传递它。

如果您想使用这些新钩子重构您的组件,您可以先更新使用matchlocationhistory对象的组件。

// before
function userComponent({ match, location, history }) {
  let { slug } = match.params
  // ...
}

// after
function userComponent() {
  let { slug } = useParams()
  let location = useLocation()
  let history = useHistory()
  // ...
}
Enter fullscreen mode Exit fullscreen mode

之后,您可以更新<Route>导航组件中可能存在的奇怪的组件。

// before
<Switch>
  <Route path="/user/:id" component={userComponent} />
</Switch>

// after
<Switch>
  <Route path="/user/:id">
    <userComponent />
  </Route>
</Switch>
Enter fullscreen mode Exit fullscreen mode

你对 React Router Hooks 有什么看法?请在下方分享你的评论。


全面了解生产 React 应用程序

调试 React 应用可能很困难,尤其是当用户遇到难以复现的问题时。如果您对监控和跟踪 Redux 状态、自动显示 JavaScript 错误以及跟踪缓慢的网络请求和组件加载时间感兴趣,请尝试 LogRocket。

替代文本

LogRocket就像 Web 应用的 DVR,可以记录 React 应用上发生的所有事件。您无需猜测问题发生的原因,而是可以汇总并报告问题发生时应用程序的状态。LogRocket 还可以监控应用的性能,并报告客户端 CPU 负载、客户端内存使用情况等指标。

LogRocket Redux 中间件包为您的用户会话增加了一层额外的可见性。LogRocket 会记录 Redux 存储中的所有操作和状态。

实现 React 应用程序调试方式的现代化 —开始免费监控。


React Router hooks 将使您的组件更清洁,该帖子首先出现在LogRocket 博客上。

文章来源:https://dev.to/bnevilleoneill/react-router-hooks-will-make-your-component-cleaner-3o70
PREV
使用 NestJS 将你的 Node 后端提升到新的水平
NEXT
了解 JavaScript 数据结构