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的时候可能会有这样的错误

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]

HashRouter和BrowserRouter的区别

1. 表现上的区别
    HashRouter:/#/path
    BrowserRouter:/path
        在生产环境中,一定需要后台配合,如果我们直接访问某一个子地址,会出现404问题,后台需要做重定向
2. 实现上的区别(原理最基本的点)
    HashRouter:锚点  
    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属性!!淦!

            
{/* 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});
    

    withRouter(v6版本弃用)

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

    使用 useNavigate 即可 

    路由嵌套

    V5:

    1. 作为上一级路由的子元素
        ```
            
                
                
                
             
        ```
    2. 在父级视图中,要给子视图显示的空间
        `{ this.props.children }`

     React6文档

    React Router 6 | BruceBlogReact路由基础知识V5->V6_第1张图片https://brucecai55520.gitee.io/bruceblog/notes/react/react-router6.html#%E6%A6%82%E8%BF%B0

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

    你可能感兴趣的:(JavaScript,react)