react-router-dom6

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 用于 路由之间共享状态

一、嵌套的路由配置

一级路由创建

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>
  )
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值