React路由基础知识V5->V6

目录

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文档


React路由:React-Router

官网文档

https://reactrouter.com/web/guides/quick-start

React路由基础

1. 安装依赖:`cnpm install --save react-router-dom`
2. 路由配置:
    import { BrowserRouter as Router,Route } from "react-router-dom"
    <Router>
        <Route path="/about" component={ About }></Route>
        <Route path="/home" component={ Home }></Route>
    </Router>

 在使用router的时候可能会有这样的错误

A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.

 这是因为在 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'

<Routes>
  <Route path="/home" element={<Home />} />
  <Route path="/about" element={<About />} />
</Routes>

 在 V5 版本则是这样使用:

import { BrowserRouter, Link, Route, Switch } from "react-router-dom"
import Home from './components/Home/Home'
import About from './components/About/About'

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

 也可以降低版本 $ cnpm i react-router-dom@5.2.0

HashRouter和BrowserRouter的区别

1. 表现上的区别
    HashRouter:/#/path
    BrowserRouter:/path
        在生产环境中,一定需要后台配合,如果我们直接访问某一个子地址,会出现404问题,后台需要做重定向
2. 实现上的区别(原理最基本的点)
    HashRouter:锚点  <a href="#/about"></a>
    BrowserRouter:H5新特性,History.pushState()方法

Link跳转

1. 跳转:link -> to:跳转的路径
2. Link:在浏览器中,最终渲染成a标签

exact和strict严格模式匹配

exact:严格模式匹配
strict:具体路径 /,使用之前,必须先添加exact

Switch(V6弃用)和404页面

Switch:当前页面匹配,只匹配一个
NotFound:404页面匹配

  react 导入 react-router-dom引入Switch报 ‘Switch‘ is not exported from ‘react-router-dom‘

 这是因为react-router-domV5升级到V6后,有些使用做了一些改变:

1) Switch 重命名为 Routes

2) Route 的新特性变更 ,component/render被element替代

3) 嵌套路由变得更简单

具体变化有以下:

  • Route children 已更改为接受子路由。
  • 比Route exact 和 Route strict更简单的匹配规则。
  • Route path 路径层次更清晰。

         新API:Outlet    多个 Routes   

4) 用 useNavigate 代替 useHistory

5) 新钩子 useRoutes 代替 react-router-config

6) 大小减少:从20kb到8kb

详情icon-default.png?t=M85Bhttps://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属性!!淦!

            <div>
                {/* react-router-dom v5的实现方式 */}
                {/* <NavLink activeClassName="activeCls" className="list-item" {...this.props}/> */}

                {/* react-router-dom v6的实现方式 */}
                <NavLink className={({ isActive }) => "list-item" + (isActive ? " activeCls" : "")} {...this.props} />
            </div>

 react-router-domV6版本改版踩坑

路由跳转携带参数

1. 常规传递参数方式(restfull API)
    1. 在路由配置页面增加key:`<Route path="/details/:id" component={ Details }></Route>`
    2. 在页面跳转的部分传递参数:`<Link to={`/details/${ ele.id }`}>{ ele.title }</Link>`
    3. 对应页面读取参数:`this.props.match.params.id`
2. queryString
    1. 跳转携带参数:`<li><NavLink to="/query?name=iwen">参数</NavLink></li>`
    2. 读取数据:
        1. 安装依赖:`npm install --save query-string`
        2. 读取数据:`const { name } = qs.parse(this.props.location.search);`

 params参数传递:

v5版本:

//路由链接(携带参数):
<Link to='/demo/test/tom/18'}>详情</Link> 
//或 <Link to={{ pathname:'/demo/test/tom/18' }}>详情</Link>

//注册路由(声明接收):
<Route path="/demo/test/:name/:age" component={Test}/>
    
//接收参数:
this.props.match.params

v6版本:

//路由链接(携带参数):
<Link to={{ pathname:`/b/child1/${id}/${title}` }}>Child1</Link>
//或 <Link  to={`/b/child1/${id}/${title}`}>Child1</Link> 

//注册路由(声明接收):
<Route path="/b/child1/:id/:title" element={<Test/ >} />
    
//接收参数:接收参数的组件一定要是函数式声明的(class不可以)!!!
import { useParams } from "react-router-dom";
const params = useParams();
//params参数 => {id: "01", title: "消息1"}

 search参数:

 v5版本:

//路由链接(携带参数):
<Link to='/demo/test?name=tom&age=18'}>详情</Link>

//注册路由(无需声明,正常注册即可):
<Route path="/demo/test" component={Test}/>
        
//接收参数:
this.props.location.search

//备注:获取到的search是urlencoded编码字符串(例如: ?id=10&name=zhangsan),需要借助query-string解析参数成对象

 v6版本:

//路由链接(携带参数):
 <Link className="nav" to={`/b/child2?age=20&name=zhangsan`}>Child2</Link>

//注册路由(无需声明,正常注册即可):
<Route path="/b/child2" component={Test}/>
        
//接收参数方法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 (
            <HashRouter>
                <NavLink />
                <Routes>
                        <Route path='/home' element={<Home />}></Route>
                        <Route path="/" element={<Navigate replace to="/home" />} />
                        {/* <Route path='/about' element={<News />}></Route>使用Routes 只匹配第一个/about */}
                        <Route path='/about' element={<About />}></Route>
                        <Route path='/news' element={<News />}></Route>
                        <Route path="*" element={ <NotFound /> }></Route>
                </Routes>
            </HashRouter>
        )
    }
}


import React, { Component } from 'react'
import { Link, NavLink } from 'react-router-dom'
import './style.css'
export default class NavMain extends Component {
    render() {
        return (
            <div className="nav">
                <ul>
                    {/* <li><NavLink activeClassName="selected" exact strict  to="/">首页</NavLink></li>
                    <li><NavLink activeClassName="selected" exact to="/about">关于</NavLink></li> */}
                    {/* <li><NavLink activeClassName="selected" exact to="/news">新闻</NavLink> */}
                    <li><NavLink className={({ isActive }) => "active" + (isActive ? " selected" : "")} {...this.props} to="/news">新闻</NavLink></li>
                    <li><NavLink className={({ isActive }) => "active" + (isActive ? " selected" : "")} {...this.props} to="/about">关于</NavLink></li>
                    <li><NavLink className={({ isActive }) => "active" + (isActive ? " selected" : "")} {...this.props} to="/home" exact='true'>首页</NavLink></li>
                    {/* exact='true' 没效果?*/}
                    {/* </li> */}
                </ul>
            </div>
        )
    }
}


编程式导航

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 }});
前进
<button onClick={() => navigate(1)}>Go Forword</button>
后退
<button onClick={() => navigate(-1)}>Go back</button>
前进或后退几步
<button onClick={() => navigate(2)}>Go</button>
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});

withRouter(v6版本弃用)

路由的高阶组件:让没有被路由所直接管理的组件具有路由对象,history对象

使用 useNavigate 即可 

路由嵌套

V5:

1. 作为上一级路由的子元素
    ```
        <User path="/user">
            <Redirect from="/user" to="/user/info"></Redirect>
            <Route path="/user/info" component={ UserInfo }></Route>
            <Route path="/user/order" component={ UserOrder }></Route>
        </User> 
    ```
2. 在父级视图中,要给子视图显示的空间
    `{ this.props.children }`

 React6文档

React Router 6 | BruceBloghttps://brucecai55520.gitee.io/bruceblog/notes/react/react-router6.html#%E6%A6%82%E8%BF%B0

 我看视频学的是V5,写代码用的V6,有点难受......,接下来学习Redux状态管理

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值