快速体验ReactRouter
首先我们需要在项目中ReactRouter的依赖,关于如何搭建React项目请参照之前的博文React入门01-从零开始快速搭建react基础开发环境。
npm i react-router-dom
我们现在来简单实现一个路由,实现最简单的路由需要使用createBrowserRouter创建路由对象,在顶层使用RouterProvider,将router对象挂载到RouterProvider组件上,这样我们就实现了一个最简单的路由。
import React from 'react';
import ReactDOM from 'react-dom/client';
// 导入路由所必须的组件和方法
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
// 创建router
const router = createBrowserRouter([
{
path: '/page1',
element:<div>page1</div>
},
{
path: '/page2',
element:<div>page2</div>
}
])
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
{/* 挂载RouterProvider */}
<RouterProvider router={router}>
</RouterProvider>
);
抽象路由模块
遵循分层的思想,我们的路由模块也需要在专门的目录进行存放,同样在router目录下有modeles用于存放不同业务区分的子路由,index.js组装成总的路由,然后再最外层的index.js文件当中进行挂载。
目录结构如下图所示:
在编写路由内容时我们首先要创建两个组件,如下图所示:
Login组件和Article组件编写的内容分别如下所示:
//Article组件
export const Article = () => {
return <div>this is article page</div>
}
// Login组件
export const Login = () => {
return <div>this is login page</div>
}
在准备好组件之后,我们在modules目录下的homeRouter.js和articleRouter.js下面分别编写以下内容,定义各自子模块的路由内容:
import { Article } from "../../page/Article";
export const articleRouter = [
{
path: '/article',
element: <Article />
}
]
import { Login } from "../../page/Login"
export const homeRouter = [
{
path: '/login',
element: <Login />
}
]
接着在router/index.js下组装store,用到的方法是createBrowserRouter。
// modules目录下的子路由
import { articleRouter } from "./modules/articleRouter";
import { homeRouter } from "./modules/homeRouter";
// 导入创建路由的函数
import { createBrowserRouter } from 'react-router-dom';
export const router = createBrowserRouter([
...homeRouter,
...articleRouter
])
然后我们就可以将创建好的router挂载到RouterProvider组件上了,代码如下所示,这样我们就完成了路由的抽象分层处理,让整个项目更清晰明了:
import { RouterProvider } from 'react-router-dom';
import router from './router';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
this is parent page
{/* 挂载RouterProvider */}
<RouterProvider router={router}>
</RouterProvider>
);
路由导航跳转
实现路由跳转有两种方式:
- 使用react-router-dom提供的Link组件,组件上的to属性绑定路由的path实现跳转。
- 使用react-router-dom提供的useNavigate函数,调用该Hook将会返回一个方法,调用该方式传递path路径就可以实现跳转。
下面我们从代码层面看一下如何实现,首先是 Link组件。
import { Link } from "react-router-dom"
// Login组件
const Login = () => {
return <div><Link to='/article'>点击我去article</Link>this is login page</div>
}
export default Login
然后是是使用useNavigate。
import { useNavigate } from "react-router-dom"
// Article组件
const Article = () => {
const navigate = useNavigate()
return <div><button onClick={()=>{navigate('/login')}}>点击我去login页面</button>this is article page</div>
}
export default Article
路由跳转传参
路由传参有两种方式一种是以SearchParams的ing是传递参数(形如?username=Billy&password=1434115),另一种方式以Params的形式传递参数(形如/article/114/John)。
知道了两种传递参数的方式,那么如何实现呢?其实很简单,之间修改Link或者navigate传递的字符串形式就行,如下面的代码所示。
<button onClick={()=>{navigate('/login?username=Billy&password=1434115')}}>点击我去login页面</button>
<Link to='/article/112/john'>点击我去article</Link>
获取传递参数
以SearchParams形式参数获取很简单,只需要使用提供的useSearchParams,获取返回参数后调用get方法即可获取参数值。
const searchPara = useSearchParams()
// 获取username和password参数
const username = searchPara.get('username')
const password = searchPara.get('password')
以Params形式传递的参数获取稍微复杂一点,我们需要修改路由为以下形式:
export const articleRouter = [
{
path: '/article/:id/:name',
element: <Article />
}
]
然后再调用和SearchParams不同德钩子函数useParams,直接从返回对象上获取传递的参数信息:
const para = useParams()
// 获取id和name参数
const id = para.id
const name = para.name
嵌套路由的配置
往往在实际开发过程当中,我们的路由并不一层的,一般一级路由由布局(layout)组成,路由跳转时我们只重新渲染组件内的二级路由,如图所示是管理端页面,直观的体现了二级路由的好处。
那么在React中如何实现这个效果呢,我们可以在一级路由下添加children属性,children属性任然是一个router列表,同时注意在一级路由要给二级路由一个入口,官方提供了<Outlet />组件作为二级路由的入口文件。
- 在一级路由下添加children,列表内容任然是router
- 在一级路由组件中添加 <Outlet />作为二级路由的入口
首先添加children。
export const homeRouter = [
{
path: '/login',
element: <Login />,
children:[
{
path: '/login/page1',
element:<div>page1</div>
},
{
path: '/login/page2',
element:<div>page2</div>
}
]
}
]
其次在一级组件添加二级路由入口<Outlet />,这样就完成了路由的嵌套。
设置默认二级路由
当我们不设置默认二级路由时,我们进入/login页面时没有二级路由的内容的,现在只需要把我们需要默认显示的二级路由的path删除然后添加index:true就可以实现,如下面的代码所示。
export const homeRouter = [
{
path: '/login',
element: <Login />,
children:[
{
// 设置默认路由
index: true,
element:<div>page1</div>
},
{
path: '/login/page2',
element:<div>page2</div>
}
]
}
]
404路由设置
当用户输入一个我们没有设置的路由的时候需要跳转到404页面,我们只需要在router里面将path设置为*,当用户访问不存在的路由的时候就会跳转到404页面,如下面的代码所示。
export const errorRouter = [
{
path: '*',
element: <div>404</div>
}
]