【React 框架】路由 / react-router-dom 相关 API / 嵌套路由 / 路由组件传递参数 / 编程式路由导航

一、概述

1、SPA 的理解

        (1)单页 Web 应用(single page web application,SPA)。

        (2)整个应用只有一个完整的页面

        (3)点击页面中的链接不会刷新页面,只会做页面的局部更新。

        (4)数据都需要通过 ajax 请求获取,并在前端异步展现。

2、路由的理解

2.1 什么是路由?

        (1)一个路由就是一个映射关系 ( key:value )。

        (2)key 为路径,value可能是 function 或 component。

2.2 路由分类

2.2.1 后端路由

        (1)理解:value 是 function,用来处理客户端提交的请求。

        (2)注册路由:router.get(path, function(req, res))。

        (3)工作过程:当 node 接收到一个请求时,根据请求路径找到匹配的路由,调用路由中的函数来处理请求,返回响应数据。

2.2.2 前端路由

        (1)浏览器端路由,value 是 component,用于展示页面内容。

        (2)注册路由:<Route path="/test" component={Test}>。

        (3)工作过程:当浏览器的path变为 /test 时,当前路由组件就会变为 Test 组件。

3、react-router-dom 的理解

        官方文档:React Router: Declarative Routing for React.js

        (1)react 的一个插件库

        (2)专门用来实现一个 SPA 应用。

        (3)基于 react 的项目基本都会用到此库。

二、路由的基本使用(语法)

1、准备路由

1.1 下载 react-router-dom 模块

        这里下载的是 v5 版本的,v6版本之后学习的时候再下载。

npm i react-router-dom@5

1.2 导入模块

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

2、使用路由

        在使用路由之前要分析好页面的整体结构,清晰的划分【导航区】和【内容展示区】

2.1 编写路由链接(导航区)

/* 原生html中,靠 <a> 标签跳转不同的页面 */
/* <a className="list-group-item" href="./about.html">About</a>
	<a className="list-group-item active" href="./home.html">Home</a> */

/* 在React中靠路由链接实现切换组件--编写路由链接 */
<Link className="list-group-item" to="/about">About</Link>
<Link className="list-group-item" to="/home">Home</Link>

2.2 注册路由(内容展示区 - 指定对应组件)

/* 注册路由 */
<Route path="/about" component={About}/>
<Route path="/home" component={Home}/>

2.3 使用路由器管理路由

        实际上,需要使用路由器对所有的路由进行管理,所以我们在 App 组件外层包裹一个 Router 。

       Router 分为: BrowserRouter、HashRouter。

import { BrowserRouter } from "react-router-dom";

const root = createRoot(document.getElementById('root'));
root.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>
)

3、路由组件与一般组件

一般组件路由组件
写法不同<Demo /><Route path="/demo" component={Demo}/>
存放位置不同compontentspages
接收到的 props 不同组件标签传递什么参数,就接收什么参数

接收到三个固定的属性

history ( 包含 location )

location

match 

三、react-router-dom 相关 API

        使用 API 时,记得一定要先导入模块哈。

1、<BrowserRouter> / <HashRouter> / <Route> / <Link>

        基础用法中有使用到,不详细说,之后需要再补充。

1.1 BrowserRouter 与 HashRouter 的区别

(1)底层原理不一样:

         ① BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。

         ② HashRouter使用的是URL的哈希值。

(2)path表现形式不一样:

         ① BrowserRouter的路径中没有#,例如:localhost:3000/demo/test。

         ② HashRouter的路径包含#,例如:localhost:3000/#/demo/test。

(3)刷新后对路由state参数的影响:

         ①BrowserRouter没有任何影响,因为state保存在history对象中。

         ②HashRouter刷新后会导致路由state参数的丢失!!!

备注:HashRouter可以用于解决一些路径错误相关的问题(比如样式丢失问题)。

2、<NavLink>

2.1 基本使用

        官方文档:https://react-router.docschina.org/web/api/NavLink

        说明:一个特殊版本的 Link,当它与当前 URL 匹配时,为其渲染元素添加样式属性。

        注意:在以下简单案例中,当点击时,会在对应标签增加 active 属性,实现点击部分的高亮效果。(这刚好和 bootstrap.css 设置相似,其他的不一定也是相同的效果)

      

2.2 <NavLink> 的封装

(1)定义 MyNavLink 组件。

import React, { Component } from 'react'
import {NavLink} from 'react-router-dom'

export default class MyNavLink extends Component {
	render() {
		// console.log(this.props);
		return (
			<NavLink activeClassName="atguigu" className="list-group-item" {...this.props}/>
		)
	}
}

(2)导入使用 MyNavLink 组件实现封装,优点是可以将相同的样式属性封装起来,在编写路由链接时只写不同的部分。

<MyNavLink to="/about">About</MyNavLink>
<MyNavLink to="/home">Home</MyNavLink>

3、<Switch>

3.1 概述

        官方文档:https://react-router.docschina.org/web/api/Switch

        说明:渲染与该地址匹配的第一个子节点 <Route> 或者 <Redirect>。(默认情况下,是遍历匹配所有路由节点,因此可以这么理解,加上 Switch 后当找到匹配的路由节点时,就不会再往下匹配了)。

3.2 基本使用

<Switch>
    <Route path="/about" component={About}/>
    <Route path="/home" component={Home}/>
    // 此时不会再显示 Test 组件的内容
    <Route path="/home" component={Test}/>
</Switch>

4、<Redirect>

4.1 概述

        官方文档:https://react-router.docschina.org/web/api/Redirect

        说明:渲染 <Redirect> 将使导航到一个新的地址。这个新的地址会覆盖 history 栈中的当前地址,类似服务器端(HTTP 3xx)的重定向。(应用:当地址没有任何节点可以匹配时,可以指定一个默认出现的页面地址。)

4.2 基本使用

<Switch>
    <Route path="/about" component={About}/>
    <Route path="/home" component={Home}/>
    <Redirect to="/about"/>
</Switch>

5、withRouter 函数

官方文档:https://react-router.docschina.org/web/api/withRouter

含义:您可以通过 withRouter 高阶组件访问 history 对象的属性和最近的 <Route> 的 match。 当路由渲染时,withRouter 会将已经更新的 match、location 和 history 属性传递给被包裹的组件。

使用:

import { withRouter } from 'react-router'
//withRouter可以加工一般组件,让一般组件具备路由组件所特有的API
//withRouter的返回值是一个新组件
const ShowTheLocationWithRouter = withRouter(ShowTheLocation)

6、解决样式丢失问题

(1)public/index.html 中引入样式时不写 ./ 写 / (常用)。

<link rel="stylesheet" href="/css/bootstrap.css">

(2)public/index.html 中引入样式时不写 ./ 写 %PUBLIC_URL%(常用)。

<link rel="stylesheet" href="%PUBLIC_URL%/css/bootstrap.css">

(3)使用 HashRouter。

7、路由的模糊匹配和严格匹配

(1)默认使用的是模糊匹配。【输入的路径必须包含匹配的路径,且顺序要一致】

(2)开启严格匹配:exact = { true }

<Route exact={true} path="/about" component={About}/>

(3)严格匹配不要随便开启,需要的时候再开启,否则可能会导致无法继续匹配二级路由。

8、嵌套路由的使用

(1)注册子路由时要写上父路由的 path 值。

(2)路由的匹配是按照注册路由的顺序进行的。

<div>
    <ul className="nav nav-tabs">
        <li>
                <MyNavLink to="/home/news">News</MyNavLink>
        </li>
        <li>
                <MyNavLink to="/home/message">Message</MyNavLink>
        </li>
    </ul>
    {/* 注册路由 */}
    <Switch>
        <Route path="/home/news" component={News}/>
        <Route path="/home/message" component={Message}/>
        <Redirect to="/home/news"/>
    </Switch>
</div>

四、向路由组件传递参数数据

1、params 参数

路由链接(携带参数):

    <Link to={'/demo/test/tom/18'}>详情</Link>

注册路由(声明接收):

    <Route path="/demo/test/:name/:age" component={Test}/>

接收参数:this.props.match.params 

2、search 参数

路由链接(携带参数):

    <Link to={'/demo/test?name=tom&age=18'}>详情</Link>

注册路由(无需声明,正常注册即可):

    <Route path="/demo/test" component={Test}/>

接收参数:this.props.location.search

备注:获取到的 search 是 urlencoded 编码字符串,需要借助 query-string 解析。

// 下载插件:npm i query-string
// 导入模块
import qs from 'query-string'

// 使用
// slice(1)是从[1]开始截取字符串,目的是去除最前面的?号
const result = qs.parse(search.slice(1))

3、state 参数

 路由链接(携带参数):

    <Link to={{pathname='/demo/test', state:{name:'tom',age:18}}}>详情</Link>

注册路由(无需声明,正常注册即可):

    <Route path="/demo/test" component={Test}/>

接收参数:this.props.location.state

备注:刷新也可以保留住参数,但是参数不在地址上体现,因此清除缓存后参数会消失。

五、编程式路由导航

1、常用 API

借助 this.prosp.history 对象上的 API 对操作路由跳转、前进、后退:

this.prosp.history.push() push(path, [state]) - (function 类型)在 history 堆栈添加一个新条目
this.prosp.history.replace()replace(path, [state]) - (function 类型)在 history 堆栈中的当前条目
this.prosp.history.goBack()goBack() - (function 类型)等同于 go(-1)
this.prosp.history.goForward()goForward() - (function 类型)等同于 go(1)
this.prosp.history.go()go(n) - (function 类型)将 history 堆栈中的指针调整 n

2、点击事件的实现

// 定义一个按钮实现 push 操作
<button onClick={() => { this.push(msgObj.id, msgObj.title) }}>push</button>
// 利用 this.props.history.push 这个API,这里传参方式是 state 
push = (id, title) => {
		this.props.history.push('/home/message/detail', { id, title })
	}

3、定时跳转的实现

	componentDidMount() {
		setTimeout(() => {
			this.props.history.push('/home/message')
		}, 2000);
	}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React Router v6中,路由嵌套的写法有所改变。以下是一个示例: ```jsx import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import { Outlet } from 'react-router-dom'; const App = () => { return ( <Router> <Routes> <Route path="/app" element={<ThisLayout />}> <Route path="/" element={<PostsList />} /> <Route path="/singlePostPage/:id" element={<SinglePostPage />} /> </Route> </Routes> </Router> ); }; const PostsList = () => { // ... return ( <section> <h2>posts</h2> {renderedPosts} <Outlet /> {/* 子路由渲染位置 */} </section> ); }; const SinglePostPage = () => { // ... }; const ThisLayout = () => { // ... }; export default App; ``` 在v6中,我们使用`Routes`组件来定义路由,而不再使用`Switch`组件。在父路由中,我们使用`Route`组件来定义子路由。子路由的元素可以通过`element`属性指定。在子路由的父组件中,我们可以使用`Outlet`组件来渲染子路由的内容。 希望这个例子能帮助你理解React Router v6中的路由嵌套写法。 #### 引用[.reference_title] - *1* [解决react-router-dom V6路由嵌套时子路由无法显示的问题](https://blog.csdn.net/frank7023/article/details/128913988)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [React Router v6 路由配置,嵌套路由](https://blog.csdn.net/Snow_GX/article/details/123656412)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [react-router-dom v6版本 嵌套路由](https://blog.csdn.net/jzh1359314792/article/details/126526047)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值