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

智能推荐

while循环&CPU占用率高问题深入分析与解决方案_main函数使用while(1)循环cpu占用99-程序员宅基地

文章浏览阅读3.8k次,点赞9次,收藏28次。直接上一个工作中碰到的问题,另外一个系统开启多线程调用我这边的接口,然后我这边会开启多线程批量查询第三方接口并且返回给调用方。使用的是两三年前别人遗留下来的方法,放到线上后发现确实是可以正常取到结果,但是一旦调用,CPU占用就直接100%(部署环境是win server服务器)。因此查看了下相关的老代码并使用JProfiler查看发现是在某个while循环的时候有问题。具体项目代码就不贴了,类似于下面这段代码。​​​​​​while(flag) {//your code;}这里的flag._main函数使用while(1)循环cpu占用99

【无标题】jetbrains idea shift f6不生效_idea shift +f6快捷键不生效-程序员宅基地

文章浏览阅读347次。idea shift f6 快捷键无效_idea shift +f6快捷键不生效

node.js学习笔记之Node中的核心模块_node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是-程序员宅基地

文章浏览阅读135次。Ecmacript 中没有DOM 和 BOM核心模块Node为JavaScript提供了很多服务器级别,这些API绝大多数都被包装到了一个具名和核心模块中了,例如文件操作的 fs 核心模块 ,http服务构建的http 模块 path 路径操作模块 os 操作系统信息模块// 用来获取机器信息的var os = require('os')// 用来操作路径的var path = require('path')// 获取当前机器的 CPU 信息console.log(os.cpus._node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是

数学建模【SPSS 下载-安装、方差分析与回归分析的SPSS实现(软件概述、方差分析、回归分析)】_化工数学模型数据回归软件-程序员宅基地

文章浏览阅读10w+次,点赞435次,收藏3.4k次。SPSS 22 下载安装过程7.6 方差分析与回归分析的SPSS实现7.6.1 SPSS软件概述1 SPSS版本与安装2 SPSS界面3 SPSS特点4 SPSS数据7.6.2 SPSS与方差分析1 单因素方差分析2 双因素方差分析7.6.3 SPSS与回归分析SPSS回归分析过程牙膏价格问题的回归分析_化工数学模型数据回归软件

利用hutool实现邮件发送功能_hutool发送邮件-程序员宅基地

文章浏览阅读7.5k次。如何利用hutool工具包实现邮件发送功能呢?1、首先引入hutool依赖<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.19</version></dependency>2、编写邮件发送工具类package com.pc.c..._hutool发送邮件

docker安装elasticsearch,elasticsearch-head,kibana,ik分词器_docker安装kibana连接elasticsearch并且elasticsearch有密码-程序员宅基地

文章浏览阅读867次,点赞2次,收藏2次。docker安装elasticsearch,elasticsearch-head,kibana,ik分词器安装方式基本有两种,一种是pull的方式,一种是Dockerfile的方式,由于pull的方式pull下来后还需配置许多东西且不便于复用,个人比较喜欢使用Dockerfile的方式所有docker支持的镜像基本都在https://hub.docker.com/docker的官网上能找到合..._docker安装kibana连接elasticsearch并且elasticsearch有密码

随便推点

Python 攻克移动开发失败!_beeware-程序员宅基地

文章浏览阅读1.3w次,点赞57次,收藏92次。整理 | 郑丽媛出品 | CSDN(ID:CSDNnews)近年来,随着机器学习的兴起,有一门编程语言逐渐变得火热——Python。得益于其针对机器学习提供了大量开源框架和第三方模块,内置..._beeware

Swift4.0_Timer 的基本使用_swift timer 暂停-程序员宅基地

文章浏览阅读7.9k次。//// ViewController.swift// Day_10_Timer//// Created by dongqiangfei on 2018/10/15.// Copyright 2018年 飞飞. All rights reserved.//import UIKitclass ViewController: UIViewController { ..._swift timer 暂停

元素三大等待-程序员宅基地

文章浏览阅读986次,点赞2次,收藏2次。1.硬性等待让当前线程暂停执行,应用场景:代码执行速度太快了,但是UI元素没有立马加载出来,造成两者不同步,这时候就可以让代码等待一下,再去执行找元素的动作线程休眠,强制等待 Thread.sleep(long mills)package com.example.demo;import org.junit.jupiter.api.Test;import org.openqa.selenium.By;import org.openqa.selenium.firefox.Firefox.._元素三大等待

Java软件工程师职位分析_java岗位分析-程序员宅基地

文章浏览阅读3k次,点赞4次,收藏14次。Java软件工程师职位分析_java岗位分析

Java:Unreachable code的解决方法_java unreachable code-程序员宅基地

文章浏览阅读2k次。Java:Unreachable code的解决方法_java unreachable code

标签data-*自定义属性值和根据data属性值查找对应标签_如何根据data-*属性获取对应的标签对象-程序员宅基地

文章浏览阅读1w次。1、html中设置标签data-*的值 标题 11111 222222、点击获取当前标签的data-url的值$('dd').on('click', function() { var urlVal = $(this).data('ur_如何根据data-*属性获取对应的标签对象

推荐文章

热门文章

相关标签