react-router-dom6,react路由6和5的区别,一文搞懂react-router-dom6-程序员宅基地

技术标签: react.js  前端  javascript  

router-router-dom6 就是当前react路由的最新版本 在2021年11月发布 已经是路由推荐版本

react-router-dom6的变化

  • 将 Switch 升级为 Routes

  • 路由匹配组件参数 由 component 改为 element

  • 相对路径识别(子路由不需要补全父路由的path,react会自动补全)

  • 用 useNavigate 替代 useHistory

  • 废弃 Redirect 标签,使用 Navigate 标签实现路由重定向

  • 优化路由嵌套,添加 outlet 标签(路由出口,路由组件的显示。相当于vue-router里的<router-view>)

  • 使用 index 标识默认路由

  • 添加 useResolvedPath hooks

  • 添加 useSearchParams 读取和设置url参数

  • link 标签跳转的path 将支持 . 和 .. 这种语法(类比于 terminal 中的 cd .. 返回上级菜单 )

  • path 通配符将只支持 * 和 :(以前的?等将不再支持)

  • 添加 useOutletContext 用于 路由之间共享状态

安装

 npm install --save react-router-dom

 一、嵌套式路由配置:

一级路由创建

1.新建views文件夹 容纳路由页面 新建router文件夹容纳路由配置

./src/router/index.ts
​
import React from 'react'
// 1.引用路由配置
import {Route} from "react-router-dom"
// 2.引用路由页面
import Home from "../views/Home.jsx"
import Phone from "../views/Phone.jsx"
import Shop from "../views/Shop.jsx"
​
​
export default function index() {
  return (
    <>
        {/* 3.设置路由规则 */}
    
          <Route path="/home" element={<Home/>}></Route>
          <Route path="/phone" element={<Phone/>}></Route>
          <Route path="/shop" element={<Shop/>}></Route>
​
    </>
  )
}
​

2.设置路由配置放到到入口文件中

./src/index.tsx
​
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
// 1.引用路由配置文件
import App from './router';
import {BrowserRouter} from "react-router-dom"
​
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
        <BrowserRouter>
                 <App />
        </BrowserRouter>
 
);

3.运行之后发现如下错误

Uncaught Error: A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.
​
错误是说Route组件不能直接渲染  必须用一个Routes组件进行包裹使用  注意在V6版本中 Routes就是V5版本的Switch组件

./src/router/index.ts进行修改,用<Routes>标签包裹<Route>


import React from 'react'
// 引用Routes
import {Route,Routes} from "react-router-dom"
​
import Home from "../views/Home.jsx"
import Phone from "../views/Phone.jsx"
import Shop from "../views/Shop.jsx"
export default function index() {
  return (
    <>
   
        {/* 使用唯一渲染 */}
            <Routes>
                <Route path="/home" element={<Home/>}></Route>
                <Route path="/phone" element={<Phone/>}></Route>
                <Route path="/shop" element={<Shop/>}></Route>
            </Routes>
    
    </> 
  )
}
​

路由重定向

Navigate
import React from 'react'
​
import {Route,Routes,Navigate} from "react-router-dom"
​
import Home from "../views/Home.jsx"
import Phone from "../views/Phone.jsx"
import Shop from "../views/Shop.jsx"
export default function index() {
  return (
    <>  
            <Routes>
                <Route path="/home" element={<Home/>}></Route>
                <Route path="/phone" element={<Phone/>}></Route>
                <Route path="/shop" element={<Shop/>}></Route>
​
                {/* 设置路由重定向 */}
                <Route path="/" element={<Navigate to="/home"/>}></Route>
            </Routes>
    </>
        
  )
}

404页面

import React from 'react'
​
import {Route,Routes,Navigate} from "react-router-dom"
​
import Home from "../views/Home.jsx"
import Phone from "../views/Phone.jsx"
import Shop from "../views/Shop.jsx"
import No from "../views/No.jsx"
export default function index() {
  return (
    <>
            <Routes>
                <Route path="/home" element={<Home/>}></Route>
                <Route path="/phone" element={<Phone/>}></Route>
                <Route path="/shop" element={<Shop/>}></Route>
​
                
                <Route path="/" element={<Navigate to="/home"/>}></Route>
                {/* 404 */}
                <Route path="*" element={<No/>}></Route>
            </Routes>
    </>
        
  )
}

二级路由

1.新建二级路由页面 与规则的配置

./src/router/index.ts
​
import React from 'react'
​
import {Route,Routes,Navigate} from "react-router-dom"
​
import Home from "../views/Home.jsx"
import Phone from "../views/Phone.jsx"
import Shop from "../views/Shop.jsx"
import No from "../views/No.jsx"
import Era from "../views/er/Era.jsx"
import Erc from "../views/er/Erc.jsx"
export default function index() {
  return (
    <>
            <Routes>
                <Route path="/home" element={<Home/>}>
                    {/* 在一级路由规则中直接嵌套 */}
                    {/* 
                        <Route path="/home/era" element={<Era/>}></Route>
                        <Route path="/home/erc" element={<Erc/>}></Route> 
                     */}
                    {/* 也可以直接使用下面的相对路径写法 两个写法是相同的 */}
                    <Route path="era" element={<Era/>}></Route>
                    <Route path="erc" element={<Erc/>}></Route>
                </Route>
          
                <Route path="/phone" element={<Phone/>}></Route>
                <Route path="/shop" element={<Shop/>}></Route>
​
                
                <Route path="/" element={<Navigate to="/home"/>}></Route>
                <Route path="*" element={<No/>}></Route>
            </Routes>
    </>
        
  )
}

2.设置路由出口 Outlet

./src/app.tsx
​
import React from 'react'
import {Outlet} from "react-router-dom"
​
export default function Home() {
  return (
    <div>
      home
      <Outlet></Outlet>
    </div>
  )
}
​

路由导航

声明式

Link与NavLink方式进行跳转

<Link to="/home">home</Link>
<Link to="/phone">phone</Link>
 Link to="/shop">shop</Link>
        
        或者
        
<NavLink to="/home">home</NavLink>
<NavLink to="/phone">phone</NavLink>
<NavLink to="/shop">shop</NavLink>

修改NavLink默认类名--》NavLink默认选中类名为active 如果想修改 还是使用className来修改里面传入回调函数

import React from 'react'
import {NavLink} from "react-router-dom"
​
export default function Demolink() {
  return (
    <div>
       <NavLink to="/home" className={({isActive})=>isActive?'xiaoming':''}>home</NavLink>
        <NavLink to="/phone"  className={({isActive})=>isActive?'xiaoming':''}>phone</NavLink>
        <NavLink to="/shop"  className={({isActive})=>isActive?'xiaoming':''}>shop</NavLink>
    </div>
  )
}
编程式

使用 useNavigate()来完成

import React from 'react'
// 1.引用
import {useNavigate} from "react-router-dom"
​
export default function Demolink() {
    // 2.调用
    let navigate=useNavigate()
​
    let fun=()=>{
        // 3.使用
        navigate("/home")
    }
  return (
    <div>
        <button onClick={fun}>点我去home</button>
    </div>
  )
}
​

路由传参

params方式

1.配置接受参数

<Route path="/phone/:id" element={<Phone/>}></Route>

2.传参

import React from 'react'
import { useNavigate } from "react-router-dom";
export default function Shop() {
    let navigate = useNavigate();
    let fun=()=>{
        // 编程式
        navigate('/phone/我是参数')
    }
  return (
    <div>
      shop
      <button onClick={fun}>点我使用params方式发送数据给phone</button>
          //声明式
      <Link to='/phone/我是参数'>点我使用params方式发送数据给phone</Link>
    </div>
  )
}
​

3.接参 用 useParams

import React from 'react'
import { useEffect } from 'react';
// 通过useParams接受路由传值
import { useParams } from "react-router-dom";
export default function Phone() {
    const params = useParams();
    // js接收
    useEffect(()=>{
        console.log(params.id)
    },[])
  return (
    <div>
        {/* 页面接收 */}
      phone--{params.id}
     
    </div>
  )
}

特点

参数会在url后面拼接传递 localhost:xxxx/phone/我是参数 并且刷新不丢失

search方式

1.传参

import React from 'react'
import { useNavigate,Link} from "react-router-dom";
export default function Shop() {
    let navigate = useNavigate();
    let fun=()=>{
        // 发送
        navigate('/phone?id=999&key=val&key=val')
    }
  return (
    <div>
      shop
      <button onClick={fun}>点我使用params方式发送数据给phone</button>
      {/* 声明式发送方式 */}
      <Link to={
   { pathname:`/phone?id=999` }}>Child</Link>
    </div>
  )
}

2.接参

import React from 'react'
import { useEffect } from 'react';
// 通过useSearchParams接受路由传值
import { useSearchParams } from "react-router-dom";
export default function Phone() {
  // 返回数组长度为2的数据 第一个为传递过来的数据  第二个是修改传递过来的数据
  const [searchParams, setSearchParams] = useSearchParams();
    // js接收
    useEffect(()=>{
        console.log(searchParams.get("id"))
    },[])
  return (
    <div>
        {/* 页面接收 */}
      phone--{searchParams.get('id')}
     
    </div>
  )
}

修改接收的路由参数---在有的项目里面 点击顺便看看类似的功能

import React from 'react'
import { useEffect } from 'react';
// 通过useSearchParams接受路由传值
import { useSearchParams } from "react-router-dom";
export default function Phone() {
  // 返回数组长度为2的数据 第一个为传递过来的数据  第二个是修改传递过来的数据
  const [searchParams, setSearchParams] = useSearchParams();
  
    useEffect(()=>{
        console.log(searchParams.get("id"))
    },[])
  return (
    <div>
      
      phone--{searchParams.get('id')}
      {/* // 同时页面内也可以用第二个参数方法来改变路由 */}
      <button onClick={()=>{setSearchParams({"id":2})}}>点我修改接收的路由参数</button>
    </div>
  )
}
特点

参数会在url后面拼接传递 localhost:xxxx/phone?id=2 并且刷新不丢失

state方式

传参:

<Link to="/Detail" state={
   { id: "q01001" }}>state:01001</Link>

接参:

import React from 'react';
import {useLocation} from "react-router-dom";
​
export default function Detail() {
​
  const location  = useLocation(); 
  console.log("location.state.id",location.state.id);
    
  return (
    <div>
      <p>location.state.id:{location.state.id}</p>
    </div>
  )
}

路由懒加载--扩展

1.修改引用方式 lazy()按需引用

// 1.修改引用方式 使用lazy方法引用
// import Home from "../views/Home.jsx"
const Home=React.lazy(()=> import ("../views/Home.jsx"))

2.修改调用方式 Suspense 懒加载加载进来的,所以渲染页面的时候可能会有延迟,但使用了Suspense之后,可优化交互。提示等待信息(有可能加载速度很快看不见等待提示)

{/* <Route path="/home" element={<Home/>}> */}
                {/* 2修改使用方式 */}
<Route path="/home" element={<React.Suspense fallback={<>请稍等。。</>}> <Home/></React.Suspense>}>

但是如果一个个都这样写太麻烦了 我们可以封装一下

let lazyload=(path)=>{
  let Com=React.lazy(()=> import (`../views/${path}`))
  return (
    <React.Suspense fallback={<>请等待·····</>}>
      <Com/>
    </React.Suspense>
  )
} 

使用

 <Route path="/home" element={lazyload("Home")}>

二、分离式路由配置

useRoutes

Hook====useRoutes 让我们可以完成类似于vue一样的配置式路由

1、不用路由懒加载。

1)、创建路由配置文件:
./routes/index.js
​
import { Navigate } from "react-router-dom";
import Goods from "../views/Goods/Goods.jsx";
import Home from "../views/Home.jsx";
import User from "../views/User.jsx";
import Detail from "../views/Goods/Detail.jsx";
import Comment from "../views/Goods/Comment.jsx";
​
const routes = [
  {
    path: "/",
    element: <Navigate to="/Home" />,
  },
  {
    path: "/Home",
    element: <Home></Home>,
  },
  {
    path: "/User",
    element: <User></User>,
  },
  {
    path: "/Goods",
    element: <Goods></Goods>,
    children: [
        {
          path: "Detail",
          element: <Detail></Detail>,
        },
        {
          path: "Comment",
          element: <Comment></Comment>
        }
    ],
  },
];
​
export default routes;
​

2)、根组件的代码:
使用 useRoutes
import './App.css';
import {Link, useRoutes } from "react-router-dom";
import routes from './routes';

function App() {
  return(
    <>
        <span>
         <Link to="/Home"> 首页</Link>
          </span>&nbsp;&nbsp;|&nbsp;&nbsp;
        <span>
         <Link to="/User"> 用户</Link>
          </span>&nbsp;&nbsp;|&nbsp;&nbsp;
        <span>
         <Link to="/Goods"> 商品</Link>
          </span>&nbsp;&nbsp;|&nbsp;&nbsp;
        <hr/>
      
        { useRoutes(routes)}

    </>
  )
}

export default App;

3)、入口文件的代码:
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter as Router } from "react-router-dom";
​
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <Router>
      <App />
    </Router>
  </React.StrictMode>
);
​
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
​
4)、Goods组件的代码:二级路由
使用路由出口 Outlet
./views/Goods.js
​
import React from "react";
import { Outlet, Link } from "react-router-dom";
​
export default function Goods() {
  return (
    <>
      <div>商品页面</div>
      <span>
        <Link to="/Goods/Detail"> 详情</Link>
      </span>
      &nbsp;&nbsp;|&nbsp;&nbsp;
      <span>
        <Link to="/Goods/Comment"> 评论</Link>
      </span>
      &nbsp;&nbsp;|&nbsp;&nbsp;
      <hr></hr>
      <Outlet></Outlet>
    </>
  );
}

2、使用路由懒加载

1)、在上一步的路由配置文件中使用 React.Lazy()函数,并把组件用<React.Suspense>包裹。

import React from "react";
import {Navigate} from "react-router-dom";
​
let lazyload=(path)=>{
    let Com=React.lazy(()=>{return import (`../views/${path}`)})
    return (
      <React.Suspense fallback={<>请等待·····</>}>
        <Com/>
      </React.Suspense>
    )
  } 
​
export default [
    {
        path:"/",
        element:<Navigate to="/home"/>
    },
    {
        path:"/home",
        element:lazyload("Home/Home"),
        children:[
            {
                path:"Son01",
                element:lazyload("Home/Son01")
            },
            {
                path:"Son02",
                element:lazyload("Home/Son02")
            }
        ]      
    },
    {
        path:"/Shop",
        element:lazyload("Shop")
    },
    {
        path:"/Phone2",
        element:lazyload("Phone")
    }
]

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/jiang7701037/article/details/131505912

智能推荐

使用nginx解决浏览器跨域问题_nginx不停的xhr-程序员宅基地

文章浏览阅读1k次。通过使用ajax方法跨域请求是浏览器所不允许的,浏览器出于安全考虑是禁止的。警告信息如下:不过jQuery对跨域问题也有解决方案,使用jsonp的方式解决,方法如下:$.ajax({ async:false, url: 'http://www.mysite.com/demo.do', // 跨域URL ty..._nginx不停的xhr

在 Oracle 中配置 extproc 以访问 ST_Geometry-程序员宅基地

文章浏览阅读2k次。关于在 Oracle 中配置 extproc 以访问 ST_Geometry,也就是我们所说的 使用空间SQL 的方法,官方文档链接如下。http://desktop.arcgis.com/zh-cn/arcmap/latest/manage-data/gdbs-in-oracle/configure-oracle-extproc.htm其实简单总结一下,主要就分为以下几个步骤。..._extproc

Linux C++ gbk转为utf-8_linux c++ gbk->utf8-程序员宅基地

文章浏览阅读1.5w次。linux下没有上面的两个函数,需要使用函数 mbstowcs和wcstombsmbstowcs将多字节编码转换为宽字节编码wcstombs将宽字节编码转换为多字节编码这两个函数,转换过程中受到系统编码类型的影响,需要通过设置来设定转换前和转换后的编码类型。通过函数setlocale进行系统编码的设置。linux下输入命名locale -a查看系统支持的编码_linux c++ gbk->utf8

IMP-00009: 导出文件异常结束-程序员宅基地

文章浏览阅读750次。今天准备从生产库向测试库进行数据导入,结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误,google一下,发现可能有如下原因导致imp的数据太大,没有写buffer和commit两个数据库字符集不同从低版本exp的dmp文件,向高版本imp导出的dmp文件出错传输dmp文件时,文件损坏解决办法:imp时指定..._imp-00009导出文件异常结束

python程序员需要深入掌握的技能_Python用数据说明程序员需要掌握的技能-程序员宅基地

文章浏览阅读143次。当下是一个大数据的时代,各个行业都离不开数据的支持。因此,网络爬虫就应运而生。网络爬虫当下最为火热的是Python,Python开发爬虫相对简单,而且功能库相当完善,力压众多开发语言。本次教程我们爬取前程无忧的招聘信息来分析Python程序员需要掌握那些编程技术。首先在谷歌浏览器打开前程无忧的首页,按F12打开浏览器的开发者工具。浏览器开发者工具是用于捕捉网站的请求信息,通过分析请求信息可以了解请..._初级python程序员能力要求

Spring @Service生成bean名称的规则(当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致)_@service beanname-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏6次。@Service标注的bean,类名:ABDemoService查看源码后发现,原来是经过一个特殊处理:当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String C..._@service beanname

随便推点

二叉树的各种创建方法_二叉树的建立-程序员宅基地

文章浏览阅读6.9w次,点赞73次,收藏463次。1.前序创建#include&lt;stdio.h&gt;#include&lt;string.h&gt;#include&lt;stdlib.h&gt;#include&lt;malloc.h&gt;#include&lt;iostream&gt;#include&lt;stack&gt;#include&lt;queue&gt;using namespace std;typed_二叉树的建立

解决asp.net导出excel时中文文件名乱码_asp.net utf8 导出中文字符乱码-程序员宅基地

文章浏览阅读7.1k次。在Asp.net上使用Excel导出功能,如果文件名出现中文,便会以乱码视之。 解决方法: fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);_asp.net utf8 导出中文字符乱码

笔记-编译原理-实验一-词法分析器设计_对pl/0作以下修改扩充。增加单词-程序员宅基地

文章浏览阅读2.1k次,点赞4次,收藏23次。第一次实验 词法分析实验报告设计思想词法分析的主要任务是根据文法的词汇表以及对应约定的编码进行一定的识别,找出文件中所有的合法的单词,并给出一定的信息作为最后的结果,用于后续语法分析程序的使用;本实验针对 PL/0 语言 的文法、词汇表编写一个词法分析程序,对于每个单词根据词汇表输出: (单词种类, 单词的值) 二元对。词汇表:种别编码单词符号助记符0beginb..._对pl/0作以下修改扩充。增加单词

android adb shell 权限,android adb shell权限被拒绝-程序员宅基地

文章浏览阅读773次。我在使用adb.exe时遇到了麻烦.我想使用与bash相同的adb.exe shell提示符,所以我决定更改默认的bash二进制文件(当然二进制文件是交叉编译的,一切都很完美)更改bash二进制文件遵循以下顺序> adb remount> adb push bash / system / bin /> adb shell> cd / system / bin> chm..._adb shell mv 权限

投影仪-相机标定_相机-投影仪标定-程序员宅基地

文章浏览阅读6.8k次,点赞12次,收藏125次。1. 单目相机标定引言相机标定已经研究多年,标定的算法可以分为基于摄影测量的标定和自标定。其中,应用最为广泛的还是张正友标定法。这是一种简单灵活、高鲁棒性、低成本的相机标定算法。仅需要一台相机和一块平面标定板构建相机标定系统,在标定过程中,相机拍摄多个角度下(至少两个角度,推荐10~20个角度)的标定板图像(相机和标定板都可以移动),即可对相机的内外参数进行标定。下面介绍张氏标定法(以下也这么称呼)的原理。原理相机模型和单应矩阵相机标定,就是对相机的内外参数进行计算的过程,从而得到物体到图像的投影_相机-投影仪标定

Wayland架构、渲染、硬件支持-程序员宅基地

文章浏览阅读2.2k次。文章目录Wayland 架构Wayland 渲染Wayland的 硬件支持简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为Wayland Architecture .Wayland 架构若是想要更好的理解 Wayland 架构及其与 X (X11 or X Window System) 结构;一种很好的方法是将事件从输入设备就开始跟踪, 查看期间所有的屏幕上出现的变化。这就是我们现在对 X 的理解。 内核是从一个输入设备中获取一个事件,并通过 evdev 输入_wayland

推荐文章

热门文章

相关标签