react路由6版本与5版本的对比

好久没写react项目了,最近使用react路由时,闹了不少乌龙。简单说下吧,react路由6版本与5版本的写法还是有很大区别的。

router-router-dom6 就是在2021年11月发布的版本,我们称之为react路由6版本。个人感觉自从react hooks一出来之后,函数式组件写法越来越受欢迎,对应的类式组件写法正在被淡出大众视野。6版本就是在此环境下产生的。

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

看看,是不是感觉跟react路由5版本差异挺大的?

关于5版本的路由写法前面已经详细介绍过,有兴趣的道友请移步我前面的博客研究一下。本文只详细介绍6版本路由的用法。

二、react路由6的基本用法

安装

npm install --save react-router-dom@6.x

使用

react项目中,我们把index.js文件改一改:

 1 // 从 react-dom/client 引入 ReactDOM
 2 import ReactDOM from 'react-dom/client'
 3 //引入BrowserRouter
 4 import { BrowserRouter } from 'react-router-dom'
 5 import App from './App'
 6 ReactDOM.createRoot(document.getElementById('root')).render(
 7   <BrowserRouter>
 8     <App />
 9   </BrowserRouter>
10 )

上面的<BrowserRouter>就是history路由(浏览器地址栏不带#),除了<BrowserRouter>还有<HashRouter>。

BrowserRouter和HashRouter两者的区别如下:

1.底层原理不同:

​ BrowserRouter使用的是H5的history API

​ HashRouter使用的是URL的哈希值

2.path的表现形式不同

​ BrowserRouter的路径中没有#,例如localhost:3000/add

​ HashRouter的路径包含#,例如localhost:3000/#/add

3.刷新后对路由state参数的影响

​ BrowserRoute没有任何影响,因为state保存在history对象中

HashRouter刷新后导致路由state参数的丢失

创建路由的方式

1.路由的基本使用

import { NavLink, Routes, Route, Navigate } from 'react-router-dom'
import About from './components/About.jsx'
import Home from './components/home.jsx'
import Children from "../components/children.jsx"

export default function App() {
  return (
    <div>
       <NavLink to="/home">Home</NavLink>
      <NavLink to="/about">About</NavLink>
      <Routes>
        <Route path="/home" element={<Home />}>
            {/*嵌套路由(子路由)*/}
            <Route path="/about" element={<About />}></Route>
        </Route>
        <Route path="/about" element={<About />}></Route>
        <Route path="/" element={<Navigate to="/home" />}></Route>
      </Routes>
    </div>
  )
}

<Navigate>:只要 <Navigate> 组件被渲染,就会修改路径,切换视图。可用于路由重定向,设置进入页面默认跳转的路由页面。

2.创建路由表

// 路由表
// routes/index.js
import { Navigate } from 'react-router-dom'
import About from '../components/About.jsx'
import Home from '../components/home.jsx'
import Children from "../components/children.jsx"
import 
const routes = [
    //路由重定向
    {
    path: '/',
    element: <Navigate to="/home" />,
  },
  {
    path: '/home',
    element: <Home />,
     //创建子路由
      children:[
      {
      path:"children",
      element:<Children/>
       }
      ]
  },
  {
    path: '/about',
    element: <About/>,
  },
  
]

export default routes

  然后在 App.jsx中挂载路由:

//App.jsx
import { NavLink,useRoutes} from 'react-router-dom'
import About from './components/About.jsx'
import Home from './components/home.jsx'
//引入路由表
import routes from './router';
export default function App() {
    //生成路由规则
    const route=useRoutes(routes);
  return (
    <div>
       <NavLink to="/home">Home</NavLink>
      <NavLink to="/about">About</NavLink>
      <div className="content">
      //在要显示路由页面的地方挂载路由
           {route}
      </div>
    </div>
  )
}

  嵌套路由(子路由):

import React, { Fragment } from 'react'
import { NavLink,Outlet} from 'react-router-dom'
export default function Home() {
  return (
    <Fragment>
       <NavLink to="/home/children">children</NavLink>
       <Outlet/>
    </Fragment>
  )
}

  <Outlet>:设置子路由的出口,即在何处渲染子路由

三、路由传参

1.传递params参数

注册路由时声明params

 {
    path: '/about /:id',
    element: <About/>,
  },

  传递参数

<NavLink to={`/about/children/${id}>children</NavLink>

  使用useParms()接收参数

import React from 'react'
import { useParams} from 'react-router-dom'
export default function Children() {
   const {id}=useParams();
  return (
    <div>About:{id}</div>
  )
}

  

2.传递search参数

注册

{
    path: '/about',
    element: <About/>,
  },

传递参数

​<NavLink to={`/about/children?id=${id}&message=${message}`}>children</NavLink>

使用 useSearchParams() 接收参数。该方法返回一个包含两个元素的数组:search 参数和修改 search 参数的方法。

import React from 'react'
import { useSearchParams } from 'react-router-dom'
export default function Children() {
  const [searchParams,setSearchParms]=useSearchParams();
    //获取相对应的值
    const id=searchParams.get('id');
    const message=searchParams.get('message');
    function change() {
    setSearchParams('id=2&message=ccc')
  }
  return (
    <div>About
      {id}:{message}
      <button onClick={change}>Change search params</button>
      </div>
  )
}

  

3.传递state参数

注册

{
    path: '/about',
    element: <About/>,
  },

传递参数

<NavLink to="/about/children" state={{id:id,message:message}}>children</NavLink>

使用 useLocation() 接收参数。该方法返回路由组件的 location 对象

import React from 'react'
import { useParams} from 'react-router-dom'
export default function Children() {
  const {
    state: { id,message },
  } = useLocation();
  return (
    <div>{id}:{message}</div>
  )
}

  useLocation()包含内容如下图:

react路由6-useLocation

 

四、路由跳转

方式一:NavLink标签的to属性
 <NavLink to="/home">Home</NavLink>
方式二:useNavigate()
import React, { Fragment } from 'react'
import { NavLink,Outlet,useNavigate} from 'react-router-dom'
export default function Home() {
    const navigate=useNavigate();
    const linkTo=()=>{
        navigate("/home/children",{
            replace:false,
            state:{
                id:id,
                message:message
            }
        })
    }
    const back=()=>{
        //后退
        navigate(1);
        //前进
        //navigate(-1);
    }
  return (
    <Fragment>
      <Button onClick={linkTo}>children</Button>
      <Button onClick={back}>children</Button>  
       <Outlet/>
    </Fragment>
  )
}

  

useNavigate() 返回一个函数,调用该函数实现编程式路由导航。函数有两种参数传递方式。

第一种方式传递两个参数:路由和相关参数。参数只能设置 replace 和 state。想要传递 params 和 search 参数直接在路由带上。

第二种方式传递数字,代表前进或后退几步。

本文参考:https://blog.csdn.net/jiang7701037/article/details/131505912

posted @ 2024-04-19 17:22  龙波帝国  阅读(60)  评论(0编辑  收藏  举报