React学习之——Router(v6)

React学习之——Router(v6)

安装

$ npm install react-router-dom@6

配置路由

入口文件导入BrowserRouter文件,并包裹根组件:

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import App from './App'

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root')
)

根组件使用 RoutesRoute 定义路由:

import React from 'react'
import { Routes, Route } from 'react-router-dom'
import { Home, About } from './components'

function App() {
  return (
    <div className="App">
      <h1>Welcome to React Router!</h1>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
      </Routes>
    </div>
  )
}

export default App

导航

通过 Link 组件导航:

import { Link } from 'react-router-dom'

function Home() {
  return (
    <main>
      <h2>Home</h2>
      <Link to="/about">About</Link>
    </main>
  )
}

function About() {
  return (
    <main>
      <h2>About</h2>
      <Link to="/">Home</Link>
    </main>
  )
}

或者使用 useNavigate Hook 导航

import { useNavigate } from 'react-router-dom'

function About() {
  let navigate = useNavigate()
  return (
    <main>
      <h2>About</h2>
      <button onClick={() => {
        navigate('/')
      }}>Home</button>
    </main>
  )
}

读取路由参数

使用 :style 语法配置路由路径,使用 useParams Hook 读取参数;带参数路由优先级比完全相等的优先级低

import { Routes, Route, useParams } from "react-router-dom"

function Article() {
  let params = useParams()
  return (
    <main>
      <h2>Article</h2>
      <p>id: { params.id }</p>
    </main>
  )
}

function App() {
  return (
    <div className="App">
      <h1>Welcome to React Router!</h1>
      <Routes>
        <Route path="/article/:id" element={<Article />} />
      </Routes>
    </div>
  )
}

嵌套路由

嵌套 Route 组件, 在父组件中使用 Outlet 组件渲染子路由组件

function Contact() {
  return (
    <main>
      <h2>Contact</h2>
      <Link to="/contact/address">Address</Link>
      <Link to="/contact/phone">Phone</Link>
      <Outlet></Outlet>
    </main>
  )
}

function Address() {
  return <div>This is address: xxxxxxxxxxx</div>
}

function Phone() {
  return <div>This is phone: xxxxxxxxxxx</div>
}

function App() {
  return (
    <div className="App">
      <h1>Welcome to React Router!</h1>
      <Routes>
        <Route path="/contact" element={<Contact />}>
          <Route path="address" element={<Address />}></Route>
          <Route path="phone" element={<Phone />}></Route>
        </Route>
      </Routes>
    </div>
  )
}

索引路由

当 URL 匹配父路由而不匹配子路由时,可以添加一个索引路由作为默认子路由来将组件渲染到出口。
子 Route 组件中添加 index 属性:

function ContactIndex() {
  return (
    <div>ContactIndex</div>
  )
}

function App() {
  return (
    <div className="App">
      <h1>Welcome to React Router!</h1>
      <Routes>
        <Route path="/contact" element={<Contact />}>
          <Route index element={<ContactIndex />}></Route>
          <Route path="address" element={<Address />}></Route>
          <Route path="phone" element={<Phone />}></Route>
        </Route>
      </Routes>
    </div>
  )
}

相对路由

不以斜杆 / 开头的 URL 的路由会被视为相对路由,修改上面的 Contact 组件:

function Contact() {
  return (
    <main>
      <h2>Contact</h2>
      <Link to="address">Address</Link>
      <Link to="phone">Phone</Link>
      <Outlet></Outlet>
    </main>
  )
}

404 路由

用于呈现没有其他路由与 URL 匹配时的路由组件,此路由优先级最低;嵌套路由也可以使用 404 路由:

function App() {
  return (
    <div className="App">
      <h1>Welcome to React Router!</h1>
      <Routes>
        <Route path="*" element={<NotFound />} />
      </Routes>
    </div>
  )
}

多组路由

一个应用程序可以有任意数量的 Routes 组件。

后代路由

Routes 组件可以放置在任何地方,包括在另一个组件树的深处,它将自动构建在呈现它们的路由的路径上,这时需要在父路由路径的末尾加上星号*:

function Article() {
  return (
    <main>
      <h2>Article</h2>
      <Routes>
        <Route path="comment" element={<Comment />} />
        <Route path="statistics" element={<Statistics />} />
      </Routes>
    </main>
  )
}

function App() {
  return (
    <div className="App">
      <h1>Welcome to React Router!</h1>
      <Routes>
        <Route path="/article/:id/*" element={<Article />} />
      </Routes>
    </div>
  )
}

完整示例代码

import { Routes, Route, Link, useParams, Outlet } from 'react-router-dom'
import './App.scss'

function Nav() {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/article/1">Article</Link>
      <Link to="/contact">Contact</Link>
    </nav>
  )
}

function Home() {
  return (
    <main>
      <h2>Home</h2>
      <Nav />
    </main>
  )
}

function About() {
  return (
    <main>
      <h2>About</h2>
      <Nav />
    </main>
  )
}

function Comment() {
  return <div>This is comment list.</div>
}

function Statistics() {
  return <div>This is statistics.</div>
}

function Article() {
  let params = useParams()
  return (
    <main>
      <h2>Article</h2>
      <Nav />
      <p>id: {params.id}</p>
      <Link to="comment">Comment</Link>
      <Link to="statistics">Statistics</Link>
      <Routes>
        <Route path="comment" element={<Comment />} />
        <Route path="statistics" element={<Statistics />} />
      </Routes>
    </main>
  )
}

function Contact() {
  return (
    <main>
      <h2>Contact</h2>
      <Nav />
      <Link to="address">Address</Link>
      <Link to="phone">Phone</Link>
      <Outlet></Outlet>
    </main>
  )
}

function ContactIndex() {
  return <div>ContactIndex</div>
}

function Address() {
  return <div>This is address: xxxxxxxxxxx</div>
}

function Phone() {
  return <div>This is phone: xxxxxxxxxxx</div>
}

function NotFound() {
  return <div>404 Not Found</div>
}

function App() {
  return (
    <div className="App">
      <h1>Welcome to React Router!</h1>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />}>
          <Route index element={<ContactIndex />}></Route>
          <Route path="address" element={<Address />}></Route>
          <Route path="*" element={<NotFound />} />
          <Route path="phone" element={<Phone />}></Route>
        </Route>
        <Route path="/article/:id/*" element={<Article />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </div>
  )
}

export default App

概念定义

  • URL - 地址栏中的URL。很多人交替使用术语“URL”和“route”,但这不是 React Router 中的路由,它只是一个URL。

  • Location - 这是一个特定于路由器的对象,基于内置浏览器的 window.location 对象。它代表“用户所在的位置”。它主要是 URL 的一种对象表示形式,但它有更多的含义。

  • Location State - 与URL中未编码的 location 保持一致的值。与 hash 或 search params (URL中编码的数据)非常相似,存储在浏览器的内存中。

  • History Stack - 当用户导航时,浏览器会跟踪堆栈中的每个位置。如果在浏览器中单击并按住“后退”按钮,您可以在那里看到浏览器的历史堆栈。

  • Client Side Routing (CSR) - 一个普通的HTML文档可以链接到其他文档,浏览器自己处理历史堆栈。Client Side Routing 使开发人员能够操纵浏览器历史堆栈,而无需向服务器发出文档请求。

  • History - 一个对象,允许React Router订阅URL中的更改,并提供 API 以编程方式操作浏览器历史堆栈。

  • History Action - pop、push 或 replace。用户可以出于以下三个原因之一访问 URL。将新条目添加到历史堆栈时的 push(通常是链接单击或程序员强制导航)。replace 与之类似,只是它替换堆栈上的当前条目,而不是推送一个新条目。最后,当用户单击浏览器中的后退或前进按钮时,会出现 pop 操作。

  • Segment - URL 或 path pattern 中 / 字符之间的部分。例如,“/users/123” 有两个 segment。

  • Path Pattern - 这些看起来像 URL,但可以有特殊字符来将URL与路由匹配,比如动态 segment “/users/:userId” 或星形 segment “/docs/*”。它们不是URL,它们是路由器将匹配的模式。

  • Dynamic Segment - 动态的 path pattern 的 segment ,这意味着它可以匹配该 segment 中的任何值。例如,模式 /users/:userId 将匹配像 /users/123 这样的 URL。

  • URL Params - 与动态 segment 匹配的URL解析值。

  • Router - 有状态的顶级组件,使所有其他组件和 hook 工作。

  • Route Config - routes objects 树,将根据当前 location 进行排序和匹配(嵌套),以创建 route matches 的分支。

  • Route - 通常具有 { path,Element } 或形状的对象或 Route Element。path 是一种 path pattern。当 path pattern 与当前 URL 匹配时,将呈现元素。

  • Route Element - 或者。通过读取此元素的 props 来创建 Route,但在其他情况下不执行任何操作。

  • Nested Routes - 因为路由可以有子路由,每个路由通过 segments 定义 URL 的一部分,所以单个 URL 可以匹配树的嵌套“分支”中的多个路由。这样可以通过 Outlet、Relative links 等实现自动布局嵌套。

  • Relative links - 不以 / 开头的链接将继承渲染它们的最近路径。这使得链接到更深层次的 URL 变得很容易,而无需知道并构建整个路径。

  • Match - 当路由与 URL 匹配时保存信息的对象,如匹配的 URL 参数和路径名。

  • Matches - 与当前 location 匹配的路由数组(或路由配置的分支)。此结构支持嵌套路由。

  • Parent Route - 带有子路由的路由。

  • Outlet - 子路由组件的渲染出口。

  • Index Route - 一个没有子路径的路由,匹配父路由 URL 时渲染。

    • Layout Route - 一种没有 path 的父路由,专门用于在特定布局中对子路由进行分组。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值