【react】 路由的基本使用 ===

目录

React 路由介绍

react模拟hash路由的实现

React路由使用的基本

路由三大对象之-Router

路由三大对象之-Route

route的作用和格式

匹配规则

exact

Switch与404

处理404页

页面跳转 Redirect

编程式导航

编程式导航的格式

history.replace和push的区别

动态路由与路由参数获取

动态路由

在组件中接收到路由的参数

嵌套路由的配置

路由小结


React 路由介绍

现代的前端应用大多都是 SPA(单页应用程序),也就是只有一个 HTML 页面的应用程序。因为它的用户体验更好、对服务器的压力更小,所以更受欢迎。

为了有效的使用单个页面来管理原来多页面的功能,前端路由应运而生。前端路由的功能:让用户从一个视图(页面)导航到另一个视图(页面)

  • 前端路由是一套映射规则,在React中,是 URL路径组件 的对应关系

  • 使用 React 路由简单来说就是:配置路径和组件(配对)

react模拟hash路由的实现

实现原理

hash值: localhost:3000/#/page1

#之后的部分就是hash值,它有两个特点:

  1. hash值的变化(地址栏中改了hash值再回车)不会重新发请求。它不是请求路径的一部分。

  2. hash值的变化会触发hashChange事件。

思路

维护一个状态curHash。

  1. 当hash变化(hashchange事件)时修改它;

  2. 根据curHash的值来决定显示哪个组件

目录结构

pages/Comment.jsx
pages/Home.jsx
pages/Search.jsx
index.js 

index.js

import React, { useEffect, useState } from 'react'
import Home from './pages/Home.jsx'
import Search from './pages/Search.jsx'
import Comment from './pages/Comment.jsx'

import ReactDom from 'react-dom'

export default function App () {
  const [curHash, setCurHash] = useState('')

  useEffect(() => {
    const onChange = () => {
      // console.log(window.location.hash)
      setCurHash(window.location.hash.slice(1))
    }
    onChange()
    window.addEventListener('hashchange', onChange)
    return () => {
      window.removeEventListener('hashchange', onChange)
    }
  }, [])
  return (
    <div>
      <ul>
        <li>
          <a href="#/home">首页</a>
        </li>
        <li>
          <a href="#/comment">评论</a>
        </li>
        <li>
          <a href="#/search">搜索</a>
        </li>
      </ul>
      <hr />
      {curHash === '/home' && <Home />}
      {curHash === '/search' && <Search />}
      {curHash === '/comment' && <Comment />}
    </div>
  )
}

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

 hash路由的原理是监听hashChange事件

React路由使用的基本

react-router-dom 在2021年10月发步了6.0版本,目前不稳定。推荐5x版本

官网:

Declarative routing for React apps at any scale | React Router (6.0)

https://v5.reactrouter.com/ (5.X)

步骤

  1. 安装包。   npm i [email protected]

    这个包提供了三个核心的组件:  HashRouter,   Route,   Link

  2. 导入包,并使用。 import { HashRouter, Route, Link } from 'react-router-dom'

          使用HashRouter包裹整个应用,一个项目中只会有一个Router
  3. 使用Link指定导航链接

          使用Route指定路由规则(哪个路径展示哪个组件)

实例代码

import React from 'react'
import ReactDom from 'react-dom'
import { HashRouter, Route, Link } from 'react-router-dom'
import Search from './pages/Search.jsx'
import Comment from './pages/Comment.jsx'
export default function App () {
  return (
    <div>
      <h1>react路由基本使用</h1>
      <HashRouter>
        <Link to="/comment">评论</Link>
        <Link to="/search">搜索</Link>

        <Route path="/comment" component={Comment} />
        <Route path="/search" component={Search} />
      </HashRouter>
    </div>
  )
}
ReactDom.render(<App />, document.getElementById('root'))

路由三大对象之-Router

了解两种路由

HashRouter :hash模式

BrowserRouter: history模式

Router 组件:包裹整个应用,一个 React 应用只需要使用一次

两种常用 Router:HashRouterBrowserRouter

  • HashRouter:使用 URL 的哈希值实现

    • 原理:监听 window 的 hashchange 事件来实现的

  • (推荐)BrowserRouter:使用 H5 的 history.pushState() API 实现

    • 原理:监听 window 的 popstate 事件来实现的

使用es6的导入重命名来统一名字: 无论导入的是哪个路由对象,都叫Router  

import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import { HashRouter as Router, Route, Link } from 'react-router-dom'

路由三大对象之-Link

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

Link组件最终会渲染成a标签,用于指定路由导航

  • to属性,将来会渲染成a标签的href属性

  • Link组件无法展示哪个link处于选中的效果

NavLink组件,一个更特殊的Link组件,可以用用于指定当前导航高亮

格式:

<NavLink to="/xxx" activeClassName="active">链接</NavLink>

说明:

  • to属性,用于指定地址,会渲染成a标签的href属性

  • activeClassName: 用于指定高亮的类名,默认active。一般不去修改。

  • exact: 精确匹配,表示必须地址栏和to的属性值 精确匹配类名才生效

代码示例

import React from 'react'
import ReactDom from 'react-dom'
import { BrowserRouter as Router, Route, Link, NavLink } from 'react-router-dom'
import Search from './pages/Search.jsx'
import Comment from './pages/Comment.jsx'
export default function App () {
  return (
    <div>
      <h1>react路由基本使用-Link</h1>
      <Router>
        <div>
          Link:
          <Link to="/search">搜索</Link>
          <Link to="/comment">评论</Link>
        </div>
        <div>
          NavLink: 自带高亮类
          <NavLink to="/" exact>主页</NavLink>
          <NavLink to="/search">搜索</NavLink>
          <NavLink to="/comment">评论</NavLink>
        </div>
        <Route path="/comment" component={Comment} />
        <Route path="/search" component={Search} />
      </Router>
    </div>
  )
}
ReactDom.render(<App />, document.getElementById('root'))

路由三大对象之-Route

route的作用和格式

  1. 作用: 决定路由匹配规则

  2. 格式:<Route path="/xx/xx" component={组件}></Route>

匹配规则

名词约定:

  1. path: Route组件中path属性的值

  2. pathname: 指的如下格式

    1. link组件中to的属性值

    2. 地址栏中的地址

模糊匹配规则

  1. 只要pathname以path开头就算匹配成功

  2. 匹配成功就加载对应组件;

  3. 整个匹配过程是逐一匹配,一个匹配成功了,并不会停止匹配

模糊匹配和精确匹配

  1. 默认是模糊匹配的

  2. 补充exact可以设置成精确匹配

代码示例

import React from 'react'
import ReactDom from 'react-dom'
import { BrowserRouter as Router, Route, NavLink } from 'react-router-dom'
const Home = () => <div>主页</div>
const Article = () => <div>文章列表页</div>
const ArticleDetail = () => <div>文章详情页</div>
export default function App () {
  return (
    <div>
      <h1>react路由基本使用</h1>
      <Router>
        <NavLink to="/">主页</NavLink>&nbsp;
        <NavLink to="/article">文章列表页</NavLink>&nbsp;
        <NavLink to="/article/123">文章详情页-123</NavLink>&nbsp;
        <hr />
        <Route path="/" component={Home} />
        <Route path="/article" component={Article} />
        <Route path="/article/123" component={ArticleDetail} />
      </Router>
    </div>
  )
}
ReactDom.render(<App />, document.getElementById('root'))

exact

<Route path="/" exact component={Home} />
  • path 的说明

    • 默认情况下,/能够匹配任意/开始的路径

    • 如果 path 的路径匹配上了,那么就可以对应的组件就会被 render

  • exact , exact 表示精确匹配某个路径

    • 一般来说,如果路径配置了 /, 都需要配置 exact 属性

Switch与404

问题

Route组件的匹配成功之后并不会停止,它可能会匹配多个组件。

解决方式

用Switch组件包裹多个Route组件。

Switch组件下,不管有多少个Route的路由规则匹配成功,都只会渲染第一个匹配的组件

import React from 'react'
import ReactDom from 'react-dom'
import {
  BrowserRouter as Router,
  Route,
  NavLink,
  Switch
} from 'react-router-dom'
const Home = () => <div>主页</div>
const Article = () => <div>文章列表页</div>
const ArticleDetail = () => <div>文章详情页</div>
export default function App () {
  return (
    <div>
      <h1>react路由基本使用</h1>
      <Router>
        <NavLink to="/">主页</NavLink>&nbsp;
        <NavLink to="/article">文章列表页</NavLink>&nbsp;
        <NavLink to="/article/123">文章详情页-123</NavLink>&nbsp;
        <hr />
        <Switch>
          <Route path="/" exact component={Home} />
          <Route path="/article" component={Article} />
          <Route path="/article/123" component={ArticleDetail} />
        </Switch>
      </Router>
    </div>
  )
}
ReactDom.render(<App />, document.getElementById('root'))

处理404页

思路: 不设置path属性,将404页对应的路由放在switch内部的最后位置

通过Switch组件非常容易的就能实现404错误页面的提示

 <Switch>
          <Route path="/" exact component={Home} />
          <Route path="/article" component={Article} />
          <Route path="/article/123" component={ArticleDetail} />
          <Route component={Page404} />
        </Switch>

页面跳转 Redirect

格式

<Redirect from="/" exact to="/comment" />

示例

  <Route path="/comment" component={Comment} />
          <Route path="/search" component={Search} />
             {/* <Route path="/" component={Comment} /> */}
          <Redirect from="/" to="/comment" />

编程式导航

页面跳转有两类方式:

  1. 用户点击链接跳转-声明式导航

  2. 写代码跳转-编程式导航

掌握history对象的使用,会用它来跳转页面。  

编程式导航的格式

import {useHistory} from 'react-router'

export default function App() {
  const history = useHistory()
  
  history.push('/find')
  // 前进或后退到某个页面,参数 n 表示前进或后退页面数量(比如:-1 表示后退到上一页)
  history.go(-1) 
  
  // 进入/frend,并替换记录
  history.replace('/frend') 
  
}

history.replace和push的区别

push:向历史记录中添加一条

replace:在历史记录中用目标记录来替换当前记录

示例

push

详情页  --> login页(push)  ----> 主页 

此时,从主页后退,会回到login页。

replace

详情页  --> login页(replace)  ----> 主页 

此时,从主页后退,会回到详情页。

动态路由与路由参数获取

问题 : 如何设置如下路由匹配规则,以显示文章详情  

<NavLink to="/article/1">文章1</NavLink>
<NavLink to="/article/2">文章2</NavLink>

动态路由

// 可以匹配 /article/1  /article/2  /article/xxx
<Route path="/article/:id" component={Article} />

说明:

  1. 上面的/:id 称为占位符。id可以改成其他的变量名。

  2. 占位符可以有多个。例如: /article/:形参1/:形参2

在组件中接收到路由的参数

有两个方式:

  1. 通过props可以

function Article(props){
    console.log(props.match.params.id)
}

  2. 通过hooks可以

impoirt { useParams } from 'react-router'
const params = useParams()
console.log(params) // 这里有数据

嵌套路由的配置

 示例代码

App () {
  return 
    <Router>
      <ul>
        <li><NavLink to="/find">发现</NavLink></li>
        <li><NavLink to="/my">我的音乐</NavLink></li>
          <li><NavLink to="/frend">朋友</NavLink></li>
      </ul>

      <Switch>
           <Route path="/find" component={Find}></Route>
          <Route path="/my" component={My}></Route>
          <Route path="/frend" component={Frend}></Route>
      </Switch>
    </Router>
}

find.js

Find(){
  return <Router>
    <ul>
    	<li><NavLink to="/find/recommand">推荐</NavLink></li>
      <li><NavLink to="/find/top">排行榜</NavLink></li>
       <li><NavLink to="/find/list">歌单</NavLink></li>
    </ul>
  
    <Switch>
         <Route path="/find/recommand" component={Com1}></Route>
  			<Route path="/my/top" component={Com2}></Route>
  			<Route path="/frend/list" component={Com3}></Route>
    </Switch>
    </Router>
}

注意:

配置嵌套路由的时候,需要对路径进行处理,必须要先匹配到父级路由,才能匹配到子路由

路由小结

用到的组件

HashRouter, BrowserRouter, Link, NavLink, Route, Redirect, Switch

执行过程

  1. 点击 Link 组件(a标签),修改了浏览器地址栏中的 url

  2. React 路由监听到地址栏 url 的变化 hashChange popState

  3. React 路由内部遍历所有 Route 组件,使用路由规则(path)与 pathname(hash)进行匹配

  4. 当路由规则(path)能够匹配地址栏中的 pathname(hash) 时,就展示该 Route 组件的内容

猜你喜欢

转载自blog.csdn.net/weixin_58726419/article/details/121389231
今日推荐