从零开始React系列: React Router

801 阅读4分钟

前言

React Router是一个用于React web应用的声明式路由库。它可以让你通过配置路由、加载和修改数据、处理导航等功能,来创建动态和交互式的用户界面。React Router的最新版本是6.11.0,它提供了一些新的数据抽象和导航钩子,以便更容易地让你的UI与数据保持同步。本文将介绍一下React Router的基本用法和特点。

引入React Router

要在你的应用中添加React Router,你需要在终端中从应用的根目录运行以下命令:

npm i -D react-router-dom

注意:本文使用的是React Router v6。如果你要从v5升级,你需要使用@latest标志:

npm i -D react-router-dom@latest

如何使用

React Router提供了一些组件和钩子,让你可以在React中定义和使用路由。路由是一种将URL和组件匹配的方式,当URL变化时,对应的组件就会渲染到页面上。这样,你就可以根据用户的操作和需求,动态地展示不同的内容。

React Router中最重要的组件是Routes和Route。Routes组件是一个容器,它包含了所有的Route组件。Route组件是一个单独的路由,它有两个属性:path和element。path属性是一个字符串,表示这个路由匹配的URL路径。element属性是一个React元素,表示这个路由渲染的组件。

例如,假设我们有三个组件:HomeAboutContact,分别对应三个页面:首页、关于我们和联系我们。我们可以用以下代码来定义路由:

import { Routes, Route } from "react-router-dom";
import Home from "./Home";
import About from "./About";
import Contact from "./Contact";

function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
      <Route path="/contact" element={<Contact />} />
    </Routes>
  );
}

这样,当用户访问/时,就会看到Home组件;当用户访问/about时,就会看到About组件;当用户访问/contact时,就会看到Contact组件。

除了Routes和Route之外,React Router还提供了其他一些组件和钩子,例如:

  • Link:一个可以导航到指定路由的链接组件。

    Link组件可以用来生成导航链接,当用户点击该链接时,React Router会执行相应的导航操作,导航到目标路由对应的页面。Link组件是通过to属性来指定目标路由的,to属性的值可以是一个字符串,也可以是一个对象。

    下面是Link组件的代码示例:

    import { Link } from 'react-router-dom';
    
    function MyComponent() {
      return (
        <div>
          <Link to="/home">Home</Link>
          <Link to="/about">About</Link>
        </div>
      );
    }
    
  • NavLink:一个可以导航到指定路由并添加激活样式的链接组件。

    NavLink组件和Link组件类似,都是用来生成导航链接的,不同的是NavLink组件可以在链接激活时添加样式。当用户访问的URL与NavLink组件的to属性匹配时,NavLink组件会自动添加active类名,我们可以通过CSS来设置该类名的样式。

    下面是NavLink组件的代码示例:

    import { NavLink } from 'react-router-dom';
    
    function MyComponent() {
      return (
        <div>
          <NavLink to="/home" activeClassName="active">Home</NavLink>
          <NavLink to="/about" activeClassName="active">About</NavLink>
        </div>
      );
    }
    
  • Navigate:一个可以执行导航操作的组件。

    Navigate组件可以用来执行导航操作,与Link和NavLink组件不同的是,Navigate组件是通过调用navigate函数来实现导航的,我们可以通过设置replace和state属性来控制导航方式和传递数据。

    下面是Navigate组件的代码示例:

    import { Navigate } from 'react-router-dom';
    
    function MyComponent() {
      const handleNavigate = () => {
        // 导航到/home路由,并设置state数据
        return <Navigate to="/home" state={{ from: '/about' }} replace={true} />;
      }
    
      return (
        <div>
          <button onClick={handleNavigate}>Navigate to Home</button>
        </div>
      );
    }
    
  • Outlet:一个可以渲染嵌套路由的占位符组件。

    Outlet组件用来渲染嵌套路由的占位符,当React Router匹配到一个父路由时,它会尝试渲染该父路由的子路由,而子路由的内容则会通过Outlet组件进行渲染。

    下面是Outlet组件的代码示例:

    import { Outlet } from 'react-router-dom';
    
    function MyComponent() {
      return (
        <div>
          <h1>My App</h1>
          <Outlet />
        </div>
      );
    }
    

    这里的Outlet组件表示嵌套路由的占位符,父路由的内容会渲染在h1标签后面,子路由的内容则会通过Outlet组件进行渲染。

  • useNavigate:一个可以返回navigate函数的钩子,用于编程式导航。

    import { useNavigate } from "react-router-dom";
    
    function MyComponent() {
      const navigate = useNavigate();
    
      function handleClick() {
        navigate("/new-page");
      }
    
      return (
        <button onClick={handleClick}>
          Navigate to a new page
        </button>
      );
    }
    
  • useLocation:一个可以返回location对象的钩子,用于获取当前URL信息。

    import { useLocation } from "react-router-dom";
    
    function MyComponent() {
      const location = useLocation();
    
      return <div>Current URL: {location.pathname}</div>;
    }
    
  • useParams:一个可以返回params对象的钩子,用于获取动态路由参数。

    import { useParams } from "react-router-dom";
    
    function UserPage() {
      const { userId } = useParams();
    
      return <div>User ID: {userId}</div>;
    }
    
  • useSearchParams:一个可以返回searchParams对象的钩子,用于获取查询字符串参数。

    import { useSearchParams } from "react-router-dom";
    
    function MyComponent() {
      const [searchParams, setSearchParams] = useSearchParams();
    
      function handleInputChange(event) {
        const value = event.target.value;
    
        setSearchParams({ search: value });
      }
    
      return (
        <div>
          <input type="text" onChange={handleInputChange} />
          <div>Current search query: {searchParams.get("search")}</div>
        </div>
      );
    }
    

这些组件和钩子可以让你更灵活地控制路由和导航,并且与React的数据流和状态管理相兼容。

总结

React Router是一个强大而灵活的路由库,它可以帮助你构建更好的React web应用。如果你想了解更多关于React Router的信息,你可以访问官方网站或者GitHub仓库