React路由,固定配置信息放置在哪里比较合适?handle属性
发布于 作者:苏南大叔 来源:程序如此灵动~很多东西,react router
框架都想在了大家的前面。比如这个react
路由的自定义属性问题,其实大家就是想存储一些配置文件,然后方便拿出来使用嘛。官方推荐的是:放在一个叫做.handle
的属性里面,并且是默认就支持这么做的。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。本文测试环境:nodejs@20.18.0
,create-react-app@5.0.1
,react-router-dom@6.27.0
,react@18.3.1
。本文主要讲述:路由配置数组里面的handle
属性是如何使用的,是如何存储配置信息和基础函数的。
基础代码
本文也是基于create-react-app
的cra
模版修改的,参考的初始化命令:
create-react-app test
cd test
npm i react-router-dom --save
npm i @babel/plugin-proposal-private-property-in-object --save-dev
npm i nodemon --save-dev
npm i esno --save-dev
可能的前提
虽然没有明确说明,使用了handle
属性的路由数组必须出现在data router
里面。但是,因为目前已知的代码编写里面,是使用useMatches()
来访问.data
和.handle
的。所以,还是有这个<RouterProvider>
的前提条件。
src/App.js
:
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import routes from "./routes";
const router = createBrowserRouter(routes);
function App() {
return (
<>
<div>Public</div>
<RouterProvider router={router}></RouterProvider>
</>
);
}
export default App;
定义一个handle
handle
,扶手,理解为配置信息。在react router
的配置数组中,是和loader
属性平级的。参考定义代码:
src/routes.js
:
import Layout from "./Layout";
import Breadcrumbs from "./Breadcrumbs";
let routes = [
{
path: "/",
element: <Layout></Layout>,
handle: {
base: "苏南大叔",
crumb: (d) => {
let p = d ? "by" + d.name : "";
return ["Level1", "人工智能" + p];
},
},
children: [
{
path: "b",
element: <Breadcrumbs></Breadcrumbs>,
loader: () => {
// return loadDataAwait();
return {"name":"uncle sunan"}
},
handle: {
base: "程序如此灵动",
crumb: (d) => {
let p = d ? " By " + d.name : "";
return ["Level2", "机器学习" + p];
},
},
},
],
},
];
export default routes;
这里直接注意.handle
属性即可,它可以是个混杂的集合,可以定义普通的变量,也可以定义函数进去。这里.loader
属性并不是必须的,并且在本文中,虽然定义了.loader
属性,也并不是使用useLoaderData()
钩子来拿到的数据,而是通过useMatches()
的结果中的.data
,进行使用的。参考文章:
src/Layout.js
:
import { Outlet, NavLink } from "react-router-dom";
let Layout = () => {
return (
<>
<style>{"a.active{color:red;font-weight:bold;}"}</style>
<br />
<NavLink to="/">默认首页</NavLink>
<NavLink to="/b">handle范例</NavLink>
<br />
<Outlet></Outlet>
</>
);
};
export default Layout;
不得不发一下牢骚,react router
官方是越来越倾向于支持data router
了,也就是createXxxRouter()
的方式。
数据访问方式
在React Router
官方文档里面,有个不完整的"面包屑"的组件例子。苏南大叔略作修改,以配合本文的内容。
src/Breadcrumbs.js
:
import React from "react";
import { useMatches } from "react-router-dom";
function Breadcrumbs() {
let matches = useMatches();
let crumbs = matches
// first get rid of any matches that don't have handle and crumb
.filter((match) => Boolean(match.handle?.crumb))
// now map them into an array of elements, passing the loader
// data to each one
.map((match) => match.handle.crumb(match.data));
console.log(crumbs);
let bases = matches
.filter((match) => Boolean(match.handle?.base))
.map((match) => match.handle.base);
console.log(bases);
return (
<ol>
{bases.map((item, index) => (
<li key={index}>{item}</li>
))}
{crumbs.map((item, index) => (
<li key={index}>{item.join(",")}</li>
))}
</ol>
);
}
export default Breadcrumbs;
这里的match.handle?.crumb
写法,很精妙。实际上是match.handle.crumb
,但是由于路由数组中不一定会有.handle
,所以做了个?
的兼容写法。另外的写法就是,有关对useMatches()
结果的筛选了。先.filter()筛选
再.map()组装
。
属性对比
这里出现了几个非常具有迷惑性的属性,对比如下:
属性 | 类型 | 路由定义中 | 路由结果中(useMatches()) | 用途 |
---|---|---|---|---|
.handle | 对象 | 存在 | 存在 | 定义一些写死的配置及函数 |
.loader | 函数 | 存在 | 不存在 | 加载远程数据或配置 |
.data | 数组或字符串 | 不存在 | 存在 | 保存远程数据的结果 |
结语
本文内容不算复杂,仅仅是对配置信息中的.handle
属性,混个脸熟而已。更多苏南大叔的react
经验文章,请参考:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。