react-routerV6 的基本使用和三种传参方式

531 阅读3分钟

react-router 的官网地址:reactrouter.com/en/main

image.png

最新的 react-router 提供了很多好玩的 hooks,我们再也不用老的方式给路由传参了。有没有被解放的感觉?

基本使用

安装react-router-dom, react-router-dom里面包含了react-router里面的所有api,所以导入一个就够了。

npm i react-router-dom -S

main.jsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <App />
);

routes/index.jsx



import React from 'react';
import App from '../App';
import Home from '../application/Home';

export default [
  {
    path: "/",
    element: <Home></Home>,
    children: [
      {
        path: "/",
        element: <Home></Home>,
      }
    ]
  }
];

app.jsx里面占位,一般占位都在布局里面占位,并不在app.js里面。

import React from 'react';
import { GlobalStyle } from './style';
import { RouterProvider, createBrowserRouter } from 'react-router-dom';
import routes from './routes/index';

//公共数据都放这里
function App() {
  const router = createBrowserRouter(routes);
  
  return (
    <RouterProvider router={router}>
      <GlobalStyle></GlobalStyle>
    </RouterProvider>
  );
}

export default App;

Home.jsx里面的内容

import React from 'react';

export default function Home() {
  return <>Home</>;
}

测试

image.png

react-router 传参有三种形式:

一、路由跳转使用navigate()

场景:跳转路由的同时,有时候要需要传递参数

由于 v6 把旧版本中的路由组件能收到的三个参数(Location,history,match) 移除了,所以 不能直接使用this.props.location.pathname 获取到当前路由。而且 withRouter也移除了。咋办?

在路由配置文件里面直接配置path,然后参数用?加进去就好了。

image.png

设置参数

import { useNavigate  } from "react-router-dom";

...
const navigate = useNavigate()
...
navigate("/recommend");
navigate("/recommend/details?id=18");

获取参数

import { useSearchParams } from "react-router-dom";

let [searchParams, setSearchParams] = useSearchParams()
console.log(searchParams.get('id')) //  18

这种方式是我们项目里面最常见的一种传参。也是我们必须掌握的方式。

二、 params 传参

params 传参需要在路由表配置的位置添加一个 参数占位。

image.png

传参

import { useNavigate  } from "react-router-dom";

 const navigate = useNavigate();
 navigate("/recommend/Eula/18");

取参

import { useParams } from "react-router-dom";

  const params = useParams()
  console.log("params:",params);// 打印 {   "name": "Eula",    "age": "18"}

现在明白useSearchParamsuseParams的区别了吗?useSearchParams获取的是?后面的参数,useParams获取的path里面占位的参数。

三、state传参

使用state传参时,参数需要放到state对象里面;但是此时path里面不能存在占位,否则不能占位。

传参

import { useNavigate  } from "react-router-dom";

  const navigate = useNavigate();
  navigate("/page1",{ state: {name:'Eula',age:"18"}});

取参数

import { useLocation } from "react-router-dom";
  ...
  let location = useLocation(); 
  console.log("params:",location);
  ...

四. 利用 URLSearchParams

'use client';

import { useSearchParams } from 'next/navigation';

export default function SortProducts() {
  const searchParams = useSearchParams();

  function updateSorting(sortOrder) {
    console.log(searchParams.toString(), 888);
    const params = new URLSearchParams(searchParams.toString());
    console.log(params, 999);
    params.set('sort', sortOrder);
    window.history.pushState(null, '', `?${params.toString()}`);
  }

  return (
    <>
      <button onClick={() => updateSorting('asc')}>Sort Ascending</button>
      <button onClick={() => updateSorting('desc')}>Sort Descending</button>
    </>
  );
}

上面例子虽然是next的,但是在react里面URLSearchParams 的使用方法是一致的。

总结

总结

传参方式使用取参
searchParams 传参navigate("/page1?name=Eula&age=18");useSearchParams()
params传参navigate("/page1/Eula/18")需要路由表添加占位: path: “/page1/:name/:age”useParams()
state传参navigate("/page1",{ state: {name:'Eula',age:"18"}})useLocation()

变化总结

lazy路由懒加载 Suspense路由加载前的渲染等待

Routers替代了react-router v5 中的 Switch

Navigate 替代了react-router v5 中的 Redirect

element替代了react-router v5 中的 component

useRoutes() 将组件转化为对象写法

路由跳转用了hooks中的useNavigate() 编程式导航

const router = useNavigate()

router(-1) 返回

路由传参使用的了useParams()和useSearchParams()还有useLocation()

const params = useParams() //params用/: 占位传

const [query] = useSearchParams() //query用?传

const {pathname} = useLocation() //获取location中pathname 路径

{params.xxxx}

{query.get('xxx’) }

Outlet 子路由出口

react-router-config 不需要了,直接用RouterProvider 就好了

image.png

# react-router6.0新版本 NavLink中activeClassName是无效的

react-router5 的写法 image.png react-router6 的写法: 利用className处理

image.png

image.png

React-Router V6 嵌套路由

如果你的路由是嵌套的,你就应该在父级下面用Outlet占位。

比如:配置文件如下:

image.png

占位

image.png 测试

image.png

如果你不占位的话,是不会显示你的内容的。所以如果你要调转的内容在Home下面,所以就应该把配置信息写在Home里面。