React RouterV6新特性

Posted 前端精髓

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React RouterV6新特性相关的知识,希望对你有一定的参考价值。

安装

npm install react-router-dom@6

配置路由

import  render  from "react-dom";
import 
  BrowserRouter,
  Routes,
  Route
 from "react-router-dom";
// import your route components too

render(
  <BrowserRouter>
    <Routes>
      <Route path="/" element=<App />>
        <Route index element=<Home /> />
        <Route path="teams" element=<Teams />>
          <Route path=":teamId" element=<Team /> />
          <Route path="new" element=<NewTeamForm /> />
          <Route index element=<LeagueStandings /> />
        </Route>
      </Route>
    </Routes>
  </BrowserRouter>,
  document.getElementById("root")
);

在以前版本的 React Router 中,当多个路由匹配一个不明确的 URL 时,你必须以某种方式对你的路由进行排序才能得到正确的渲染。V6 更聪明,会选择最具体的匹配,所以你不必再担心了。例如,URL /teams/new 匹配这两个路由:

<Route path="teams/:teamId" element=<Team /> />
<Route path="teams/new" element=<NewTeamForm /> />

由于 teams/new/teams/:teamId 是更具体的匹配 ,因此 <NewTeamForm /> 将呈现。

导航

使用 Link 让用户更改 URL 或者用 useNavigate 自己做跳转:

import  Link  from "react-router-dom";

function Home() 
  return (
    <div>
      <h1>Home</h1>
      <nav>
        <Link to="/">Home</Link> |" "
        <Link to="about">About</Link>
      </nav>
    </div>
  );

import  useNavigate  from "react-router-dom";

function Invoices() 
  let navigate = useNavigate();
  return (
    <div>
      <NewInvoiceForm
        onSubmit=async event => 
          let newInvoice = await createInvoice(
            event.target
          );
          navigate(`/invoices/$newInvoice.id`);
        
      />
    </div>
  );

读取 URL 参数

在路由路径中使用 :style 语法,组件中用 useParams() 取值:

import  Routes, Route, useParams  from "react-router-dom";

function App() 
  return (
    <Routes>
      <Route
        path="invoices/:invoiceId"
        element=<Invoice />
      />
    </Routes>
  );


function Invoice() 
  let params = useParams();
  return <h1>Invoice params.invoiceId</h1>;

请注意,路径中 :invoiceId 和参数的键 params.invoiceId 匹配,key 值必须对应。

一个非常常见的用例是在组件呈现时获取数据:

function Invoice() 
  let  invoiceId  = useParams();
  let invoice = useFakeFetch(`/api/invoices/$invoiceId`);
  return invoice ? (
    <div>
      <h1>invoice.customerName</h1>
    </div>
  ) : (
    <Loading />
  );

嵌套路由

这是 React Router 最强大的功能之一,因此您不必处理复杂的布局代码。绝大多数布局都与 URL 的片段耦合,而 React Router 完全符合了这一点。

路由可以相互嵌套,它们的路径也会嵌套(子继承父)。

function App() 
  return (
    <Routes>
      <Route path="invoices" element=<Invoices />>
        <Route path=":invoiceId" element=<Invoice /> />
        <Route path="sent" element=<SentInvoices /> />
      </Route>
    </Routes>
  );

此路由配置定义了三个路由路径:

"/invoices"
"/invoices/sent"
"/invoices/:invoiceId"

当 URL 是"/invoices/sent", 组件树为:

<App>
  <Invoices>
    <SentInvoices />
  </Invoices>
</App>

当 URL 为"/invoices/123",组件树为:

<App>
  <Invoices>
    <Invoice />
  </Invoices>
</App>

请注意随 URL (<SentInvoices><Invoice>)更改的内部组件。父路由 ( <Invoices>) 负责确保匹配的子路由使用了 <Outlet>,这是完整的示例:

import  Routes, Route, Outlet  from "react-router-dom";

function App() 
  return (
    <Routes>
      <Route path="invoices" element=<Invoices />>
        <Route path=":invoiceId" element=<Invoice /> />
        <Route path="sent" element=<SentInvoices /> />
      </Route>
    </Routes>
  );


function Invoices() 
  return (
    <div>
      <h1>Invoices</h1>
      <Outlet />
    </div>
  );


function Invoice() 
  let  invoiceId  = useParams();
  return <h1>Invoice invoiceId</h1>;


function SentInvoices() 
  return <h1>Sent Invoices</h1>;

嵌套的 url 路径映射到嵌套的组件树。这非常适合创建在布局中具有持久导航且内部部分随 URL 变化的 UI。您会注意到许多网站都具有多层布局嵌套。

索引路由

索引路由可以被认为是“默认子路由”。当父路由有多个子路由,但 URL 仅在父路由的路径上时,您可能希望将某些内容渲染到页面中。

function App() 
  return (
    <Routes>
      <Route path="/" element=<Layout />>
        <Route path="invoices" element=<Invoices /> />
        <Route path="activity" element=<Activity /> />
      </Route>
    </Routes>
  );


function Layout() 
  return (
    <div>
      <GlobalNav />
      <main>
        <Outlet />
      </main>
    </div>
  );

这个页面在“/invoices”和“/activity”上看起来很棒,但在“/”它只是一个空白页面,<main> 因为那里没有子路由渲染。为此,我们可以添加一个索引路由:

function App() 
  return (
    <Routes>
      <Route path="/" element=<Layout />>
        <Route index element=<Activity /> />
        <Route path="invoices" element=<Invoices /> />
        <Route path="activity" element=<Activity /> />
      </Route>
    </Routes>
  );

现在在“/”处,<Activity> 元素将在 Outlet 出口内呈现。

您可以在路由层次结构的任何级别拥有一个索引路由,当父级匹配但其他子级都不匹配时,该索引路由将呈现。

function App() 
  return (
    <Routes>
      <Route index element=<Home /> />
      <Route path="dashboard" element=<Dashboard />>
        <Route index element=<DashboardHome /> />
        <Route
          path="invoices"
          element=<DashboardInvoices />
        />
      </Route>
    </Routes>
  );

相对链接

相对 <Link to> 值(不以 / 开头)是相对于渲染它们的路径的路径。下面的两个链接将链接到 /dashboard/invoices 和 /dashboard/team 因为它们在 <Dashboard>. 当您更改父级的 URL 或重新排列您的组件时,这非常好,因为您的所有链接都会自动更新。

import 
  Routes,
  Route,
  Link,
  Outlet
 from "react-router-dom";

function Home() 
  return <h1>Home</h1>;


function Dashboard() 
  return (
    <div>
      <h1>Dashboard</h1>
      <nav>
        <Link to="invoices">Invoices</Link>" "
        <Link to="team">Team</Link>
      </nav>
      <hr />
      <Outlet />
    </div>
  );


function Invoices() 
  return <h1>Invoices</h1>;


function Team() 
  return <h1>Team</h1>;


function App() 
  return (
    <Routes>
      <Route path="/" element=<Home /> />
      <Route path="dashboard" element=<Dashboard />>
        <Route path="invoices" element=<Invoices /> />
        <Route path="team" element=<Team /> />
      </Route>
    </Routes>
  );

“Not Found” 路由

当没有其他路由与 URL 匹配时,您可以使用path="*". 此路由将匹配任何 URL,但具有最弱的优先级,因此路由仅在没有其他路由匹配时才会选择它。

function App() 
  return (
    <Routes>
      <Route path="/" element=<Home /> />
      <Route path="dashboard" element=<Dashboard /> />
      <Route path="*" element=<NotFound /> />
    </Routes>
  );

多组路由

尽管您应该 <Router> 在应用程序中只拥有一个,但您可以 <Routes> 在任何需要的地方拥有任意数量的。每个 <Routes> 元素独立于其他元素运行,并选择一个子路由进行渲染。

function App() 
  return (
    <div>
      <Sidebar>
        <Routes>
          <Route path="/" element=<MainNav /> />
          <Route
            path="dashboard"
            element=<DashboardNav />
          />
        </Routes>
      </Sidebar>

      <MainContent>
        <Routes>
          <Route path="/" element=<Home />>
            <Route path="about" element=<About /> />
            <Route path="support" element=<Support /> />
          </Route>
          <Route path="dashboard" element=<Dashboard />>
            <Route path="invoices" element=<Invoices /> />
            <Route path="team" element=<Team /> />
          </Route>
          <Route path="*" element=<NotFound /> />
        </Routes>
      </MainContent>
    </div>
  );


以上是关于React RouterV6新特性的主要内容,如果未能解决你的问题,请参考以下文章

react16.3的新特性

React的深入浅出

ES6新特性

react hook 新特性汇总

react16.8新特性

react新特性介绍