目录
React路由:React-Router
官网文档
React路由基础
HashRouter和BrowserRouter的区别
Link跳转
exact和strict严格模式匹配
Switch(V6弃用)和404页面
react 导入 react-router-dom引入Switch报 ‘Switch‘ is not exported from ‘react-router-dom‘
路由跳转携带参数
路由重定向
编程式导航
withRouter(v6版本弃用)
路由嵌套
React6文档
https://reactrouter.com/web/guides/quick-start
1. 安装依赖:`cnpm install --save react-router-dom`
2. 路由配置:
import { BrowserRouter as Router,Route } from "react-router-dom"
在使用router的时候可能会有这样的错误
A
is only ever to be used as the child of element, never rendered directly. Please wrap your in a .
这是因为在 React-Router v6
版本中,Route更改了使用方式。
使用 Route 需要在 Routes 标签包裹下:
import { BrowserRouter, Link, Route, Routes } from "react-router-dom"
import Home from './components/Home/Home'
import About from './components/About/About'
} />
} />
在 V5 版本则是这样使用:
import { BrowserRouter, Link, Route, Switch } from "react-router-dom"
import Home from './components/Home/Home'
import About from './components/About/About'
也可以降低版本 $ cnpm i [email protected]
1. 表现上的区别
HashRouter:/#/path
BrowserRouter:/path
在生产环境中,一定需要后台配合,如果我们直接访问某一个子地址,会出现404问题,后台需要做重定向
2. 实现上的区别(原理最基本的点)
HashRouter:锚点
BrowserRouter:H5新特性,History.pushState()方法
1. 跳转:link -> to:跳转的路径
2. Link:在浏览器中,最终渲染成a标签
exact:严格模式匹配
strict:具体路径 /,使用之前,必须先添加exact
Switch:当前页面匹配,只匹配一个
NotFound:404页面匹配
这是因为react-router-dom从V5升级到V6后,有些使用做了一些改变:
1) Switch 重命名为 Routes
2) Route 的新特性变更 ,component/render被element替代
3) 嵌套路由变得更简单
具体变化有以下:
新API:Outlet 多个 Routes
4) 用 useNavigate 代替 useHistory
5) 新钩子 useRoutes 代替 react-router-config
6) 大小减少:从20kb到8kb
详情https://blog.csdn.net/weixin_40906515/article/details/104957712
NavLink
activeStyle
activeClassName
React does not recognize the `activeClassName` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `activeclassname` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
在V6版本react-router-dom中取消了activeClassName属性!!淦!
{/* react-router-dom v5的实现方式 */}
{/* */}
{/* react-router-dom v6的实现方式 */}
"list-item" + (isActive ? " activeCls" : "")} {...this.props} />
react-router-domV6版本改版踩坑
1. 常规传递参数方式(restfull API)
1. 在路由配置页面增加key:` `
2. 在页面跳转的部分传递参数:`{ ele.title }`
3. 对应页面读取参数:`this.props.match.params.id`
2. queryString
1. 跳转携带参数:`参数 `
2. 读取数据:
1. 安装依赖:`npm install --save query-string`
2. 读取数据:`const { name } = qs.parse(this.props.location.search);`
params参数传递:
v5版本:
//路由链接(携带参数):
详情
//或 详情
//注册路由(声明接收):
//接收参数:
this.props.match.params
v6版本:
//路由链接(携带参数):
Child1
//或 Child1
//注册路由(声明接收):
} />
//接收参数:接收参数的组件一定要是函数式声明的(class不可以)!!!
import { useParams } from "react-router-dom";
const params = useParams();
//params参数 => {id: "01", title: "消息1"}
search参数:
v5版本:
//路由链接(携带参数):
详情
//注册路由(无需声明,正常注册即可):
//接收参数:
this.props.location.search
//备注:获取到的search是urlencoded编码字符串(例如: ?id=10&name=zhangsan),需要借助query-string解析参数成对象
v6版本:
//路由链接(携带参数):
Child2
//注册路由(无需声明,正常注册即可):
//接收参数方法1:接收参数的组件一定要是函数式声明的(class不可以)!!!
import { useLocation } from "react-router-dom";
import { qs } from "url-parse";
const { search } = useLocation();
const searchs = qs.parse(search)
//search参数 => {age: "20", name: "zhangsan"}
//接收参数方法2:接收参数的组件一定要是函数式声明的(class不可以)!!!
import { useSearchParams } from "react-router-dom";
const [searchParams, setSearchParams] = useSearchParams();
// console.log( searchParams.get("id")); // 12
//备注:获取到的search是urlencoded编码字符串(例如: ?age=20&name=zhangsan),需要借助 url-parse 里面的 qs.parse 解析参数成对象
Navigate代替Redirect
import React, { Component } from 'react'
import { BrowserRouter as Router, HashRouter, Route, Routes,Navigate } from 'react-router-dom'
import Home from '../views/Home'
import About from '../views/About'
import News from '../views/News'
import NotFound from "../views/NotFound"
import NavLink from '../components/NavMain'
export default class Layout extends Component {
render() {
return (
}>
} />
{/* }>使用Routes 只匹配第一个/about */}
}>
}>
}>
)
}
}
import React, { Component } from 'react'
import { Link, NavLink } from 'react-router-dom'
import './style.css'
export default class NavMain extends Component {
render() {
return (
{/* 首页
关于 */}
{/* 新闻 */}
"active" + (isActive ? " selected" : "")} {...this.props} to="/news">新闻
"active" + (isActive ? " selected" : "")} {...this.props} to="/about">关于
"active" + (isActive ? " selected" : "")} {...this.props} to="/home" exact='true'>首页
{/* exact='true' 没效果?*/}
{/* */}
)
}
}
v5:
1. push:this.props.history.push("/about")
可以返回到上一个页面(堆栈里是有缓存的)
2. repace:this.props.history.replace("/about")
不可以返回到上一个页面,上一个页面已经被新的页面替换了(完全替换,堆栈里不再有上一个页面的缓存)
v6:
// v6版本编程导航使用 useNavigate
import { useNavigate } from "react-router-dom";
export default function A() {
const navigate = useNavigate();
//...
}
push跳转携带params参数
navigate(`/b/child1/${id}/${title}`);
push跳转携带search参数
navigate(`/b/child2?id=${id}&title=${title}`);
push跳转携带state参数
navigate("/b/child2", { state: { id, title }});
前进
后退
前进或后退几步
replace跳转携带params参数
navigate(`/b/child1/${id}/${title}`,{replace: true});
replace跳转携带search参数
navigate(`/b/child2?id=${id}&title=${title}`,{replace: true});
replace跳转携带state参数
navigate("/b/child2", { state: { id, title },replace: true});
路由的高阶组件:让没有被路由所直接管理的组件具有路由对象,history对象
使用 useNavigate 即可
V5:
1. 作为上一级路由的子元素
```
```
2. 在父级视图中,要给子视图显示的空间
`{ this.props.children }`
React Router 6 | BruceBloghttps://brucecai55520.gitee.io/bruceblog/notes/react/react-router6.html#%E6%A6%82%E8%BF%B0
我看视频学的是V5,写代码用的V6,有点难受......,接下来学习Redux状态管理