react-router 的官网地址:reactrouter.com/en/main
最新的 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</>;
}
测试
react-router 传参有三种形式:
一、路由跳转使用navigate()
场景:跳转路由的同时,有时候要需要传递参数
由于 v6 把旧版本中的路由组件能收到的三个参数(Location,history,match) 移除了,所以 不能直接使用this.props.location.pathname 获取到当前路由。而且 withRouter也移除了。咋办?
在路由配置文件里面直接配置path,然后参数用?加进去就好了。
设置参数
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 传参需要在路由表配置
的位置添加一个 参数占位。
传参
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"}
现在明白useSearchParams
和useParams
的区别了吗?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 就好了
# react-router6.0新版本 NavLink中activeClassName是无效的
react-router5 的写法
react-router6 的写法: 利用className处理
React-Router V6 嵌套路由
如果你的路由是嵌套的,你就应该在父级下面用Outlet占位。
比如:配置文件如下:
占位
测试
如果你不占位的话,是不会显示你的内容的。所以如果你要调转的内容在Home下面,所以就应该把配置信息写在Home里面。