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

智能推荐

使用UmcFramework和unimrcpclient.xml连接多个SIP设置的配置指南及C代码示例

在多媒体通信领域,MRCP(Media Resource Control Protocol)协议被广泛用于控制语音识别和合成等媒体资源。UniMRCP是一个开源的MRCP实现,提供了客户端和服务端的库。UmcFramework是一个基于UniMRCP客户端库的示例应用程序框架,它帮助开发者快速集成和测试MRCP客户端功能。本文将详细介绍如何使用UmcFramework和unimrcpclient.xml配置文件连接到多个SIP设置,以及如何用C代码进行示例说明。

java.net.ProtocolException: Server redirected too many times (20)-程序员宅基地

文章浏览阅读3k次。报错:java.net.ProtocolException: Server redirected too many times (20)1.没有检查到cookie,一直循环重定向。解决:CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));URL url = new URL(url); ..._java.net.protocolexception: server redirected too many times (20)

springboot启动报错 Failed to scan *****/derbyLocale_ja_JP.jar from classloader hierarchy_failed to scan from classloader hierarchy-程序员宅基地

文章浏览阅读4.1k次。问题这是部分报错信息2019-07-11 14:03:34.283 WARN [restartedMain][DirectJDKLog.java:175] - Failed to scan [file:/D:/repo/org/apache/derby/derby/10.14.2.0/derbyLocale_ja_JP.jar] from classloader hierarchyjava...._failed to scan from classloader hierarchy

MATLAB-ones函数_matlab中ones函数-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏7次。在MATLAB中,ones函数用于创建一个指定大小的由1组成的矩阵或数组。_matlab中ones函数

解决PS等软件出现应用程序无法正常启动(0xc000007b)_photoshop应用程序无法正常启动0xc000007b。请单击“确认”关闭应用程序。-程序员宅基地

文章浏览阅读3.9w次,点赞2次,收藏9次。  在使用电脑办公过程中,安装应用程序时难免遇到无法安装或者无法正常启动的问题,这对我们使用电脑带来了诸多不便。那遇到应用程序无法正常启动的问题要如何解决呢?相信大家肯定都是十分疑问的,每次都是只能忍痛重新安装软件。今天,小编就和大家探讨下应用程序无法正常启动的解决方法,帮助大家排忧解难。0xc000007b电脑图解1  第一种方案:SFC检查系统完整性来尝试修复丢失文件  1、打开电脑搜索输入cmd.exe,选择以管理员身份运行,跳出提示框时选择继续。0xc000007b电脑图解2_photoshop应用程序无法正常启动0xc000007b。请单击“确认”关闭应用程序。

oracle介质恢复和实例恢复的异同-程序员宅基地

文章浏览阅读396次。1、概念 REDO LOG是Oracle为确保已经提交的事务不会丢失而建立的一个机制。实际上REDO LOG的存在是为两种场景准备的:实例恢复(INSTANCE RECOVERY);介质恢复(MEDIA RECOVERY)。 实例恢复的目的是在数据库发生故障时,确保BUFFER CACHE中的数据不会丢失,不会造成数据库的..._oracle 实例恢复和介质恢复

随便推点

轻松搭建CAS 5.x系列(5)-增加密码找回和密码修改功能-程序员宅基地

文章浏览阅读418次。概述说明CAS内置了密码找回和密码修改的功能; 密码找回功能是,系统会吧密码重置的连接通过邮件或短信方式发送给用户,用户点击链接后就可以重置密码,cas还支持预留密码重置的问题,只有回答对了,才可以重置密码;系统可配置密码重置后,是否自动登录; 密码修改功能是,用户登录后输入新密码即可完成密码修改。安装步骤`1. 首先,搭建好cas sso server您需要按..._修改cas默认用户密码

springcloud(七) feign + Hystrix 整合 、-程序员宅基地

文章浏览阅读141次。之前几章演示的熔断,降级 都是 RestTemplate + Ribbon 和RestTemplate + Hystrix ,但是在实际开发并不是这样,实际开发中都是 Feign 远程接口调用。Feign + Hystrix 演示:  eruka(略)order 服务工程:  pom.xml<?xml version="1.0" encoding="U..._this is order 服务工程

YOLOv7如何提高目标检测的速度和精度,基于优化算法提高目标检测速度-程序员宅基地

文章浏览阅读3.4k次,点赞35次,收藏43次。学习率是影响目标检测精度和速度的重要因素之一。合适的学习率调度策略可以加速模型的收敛和提高模型的精度。在YOLOv7算法中,可以使用基于余弦函数的学习率调度策略(Cosine Annealing Learning Rate Schedule)来调整学习率。

linux中进程退出函数:exit()和_exit()的区别_linux结束进程可以用哪些函数,它们之间有何区别?-程序员宅基地

文章浏览阅读4k次,点赞4次,收藏9次。 linux中进程退出函数:exit()和_exit()的区别(1)_exit()执行后立即返回给内核,而exit()要先执行一些清除操作,然后将控制权交给内核。(2)调用_exit函数时,其会关闭进程所有的文件描述符,清理内存以及其他一些内核清理函数,但不会刷新流(stdin, stdout, stderr ...). exit函数是在_exit..._linux结束进程可以用哪些函数,它们之间有何区别?

sqlserver55555_sqlserver把小数点后面多余的0去掉-程序员宅基地

文章浏览阅读134次。select 5000/10000.0 --想变成0.5select 5500/10000.0 --想变成0.55select 5550/10000.0 --想变成0.555select 5555/10000.0 --想变成0.5555其结果分别为:0.5000000 0.5500000 0.5550000 0.5555000一、如果想去掉数字5后面多余的0 ,需要转化一下:selec..._sql server 去小数 0

Angular6 和 RXJS6 的一些改动_angular6,requestoptions改成了什么-程序员宅基地

文章浏览阅读3.1k次。例一:import { Injectable } from '@angular/core';import { Observable } from 'rxjs';import { User } from "./model/User";import { map } from 'rxjs/operators';import { Http, Response, Headers, RequestOp..._angular6,requestoptions改成了什么

推荐文章

热门文章

相关标签