react-router-dom(6.18.0)最新指南

react-router-dom v6相比于v5变动很大,单独列出变动点觉得没有必要,可以当成全新的插件去学习并使用。官方文档的内容太多,这里整理一些平时常用的,降低入门门槛。

前提:使用 vite 新建React项目(后面我会出个相关教程的文章)

一、安装

csharp 复制代码
yarn add react-router-dom

目前版本:"react-router-dom": "^6.18.0"

二、基本使用

新建pages/login.tsx

javascript 复制代码
const Login = () => {
  return <div>登录页</div>;
};

export default Login;

新建pages/home.tsx

javascript 复制代码
const Home = () => {
  return <div>home页</div>;
};
export default Home;

1. 定义路由

新建router/routes.tsx

javascript 复制代码
/* eslint-disable react-refresh/only-export-components */
import { lazy } from 'react';

const Login = lazy(() => import('../pages/login'));
const Home = lazy(() => import('../pages/home'));

const routes = [
  {
    path: '/login',
    element: <Login />,
  },
  {
    path: '/',
    element: <Home />,
  },
];

export default routes;

新建router/index.tsx

javascript 复制代码
import { createBrowserRouter } from 'react-router-dom';

import routes from './routes';

//可传第二个参数,配置base路径 { basename: "/app"}
const router = createBrowserRouter(routes);

export default router;

2. 使用路由

修改入口main.tsx

javascript 复制代码
import { Suspense } from 'react';
import { RouterProvider } from 'react-router-dom';

import ReactDOM from 'react-dom/client';

import router from './router';

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);

root.render(
  <Suspense fallback={<div>Loading...</div>}>
    <RouterProvider router={router} />
  </Suspense>,
);

在Suspense组件中渲染lazy组件,Suspense组件置于懒加载组件之上的任何位置;如果有嵌套路由,则需再使用Suspense组件包裹

三、嵌套路由

新建pages/user.tsx

javascript 复制代码
const User = () => {
  return <div>用户页</div>;
};

export default User;

新建pages/manage.tsx

javascript 复制代码
const Manage = () => {
  return <div>管理页</div>;
};

export default Manage;

1. 定义路由

修改router/routes.tsx

javascript 复制代码
//新增
const User = lazy(() => import('../pages/user'));

const Manage = lazy(() => import('../pages/manage'));

//修改
const routes = [
  {
    path: '/login',
    element: <Login />,
  },
  {
    element: <Home />,
    children: [
      {
        path: '/',
        element: <User />,
      },
      {
        path: '/manage',
        element: <Manage />,
      },
    ],
  },
];

2. 配置嵌套路由路口

  1. 安装styled-components,一个针对React的CSS-in-JS库,用来编写组件样式
csharp 复制代码
yarn add styled-components
  1. 修改pages/home.tsx
javascript 复制代码
import { Suspense } from 'react';
import { Outlet, NavLink } from 'react-router-dom';

import styled from 'styled-components';

const Home = () => {
  return (
    <Wrapper>
      <div className="header"></div>
      <div className="main">
        <aside>
          <div className="menu_item">
            <NavLink to="/" end>
              user
            </NavLink>
          </div>
          <div className="menu_item">
            <NavLink to="/manage" end>
              manage
            </NavLink>
          </div>
        </aside>
        <section>
          <Suspense fallback={<div>Loading...</div>}>
            <Outlet />
          </Suspense>
        </section>
      </div>
    </Wrapper>
  );
};

export default Home;

const Wrapper = styled.div`
  .header {
    height: 60px;
    border: 1px solid;
  }
  .main {
    height: calc(100vh - 60px);
    display: flex;
    aside {
      width: 260px;
      border: 1px solid;
      .active {
        color: red;
      }
    }
    section {
      flex: 1;
    }
  }
`;

Outlet组件呈现匹配的子路由,类似vue的router-view组件

四、配置404页面

修改router/routes.tsx

javascript 复制代码
const routes = [
  //...
  {
    path: '*',
    element: <div>404</div>,
  },
]

404路由放在路由配置表的最后

五、声明式、编程式导航

1. 声明式导航

pages/home.tsx

ini 复制代码
<NavLink to="/manage" end>manage</NavLink>

激活时,默认类名为active。end表示精准匹配,否则当访问/manage/123时,类名也为active

2. 编程式导航

修改pages/user.tsx

javascript 复制代码
import { useNavigate } from 'react-router-dom';

const User = () => {
  const navigation = useNavigate();
  return (
    <div>
      user
      <button onClick={() => navigation('/manage')}>manage</button>
    </div>
  );
};

export default User;

六、路由传参

新建pages/file.tsx

arduino 复制代码
const File = () => {
  return <div>File</div>;
};

export default File;

1. 动态路由匹配

  1. 定义动态路由

修改router/routes.tsx

javascript 复制代码
 //新增
const File = lazy(() => import('../pages/file'));

const routes = [
  //...
  {
    element: <Home />,
    children: [
      //...
      //新增
      {
        path: '/file/:id?',
        element: <File />,
      },
    ],
  },
];
  1. 定义路由跳转

修改pages/home.tsx

ini 复制代码
  <NavLink to="/file/123" end>
    file
  </NavLink>
  1. 获取参数

修改pages/file.tsx

javascript 复制代码
import { useParams } from 'react-router-dom';
const File = () => {
  const { id } = useParams();
  return <div>{id}</div>;
};

export default File;

2. search传参

1.定义路由

修改router/index.tsx

arduino 复制代码
{
  path: "/file",
  element: <File />,
},
  1. 编程式传参
xml 复制代码
  <NavLink to={{ pathname: '/file', search: '?sort=name&id=2' }} end>
    file
  </NavLink>
  1. 命令式传参
css 复制代码
<button onClick={() => navigation({ pathname: '/file', search: '?sort=name&id=2' })}>file</button>
  1. 获取参数
dart 复制代码
import { useSearchParams } from 'react-router-dom';
const File = () => {
  const [searchParams] = useSearchParams();
  return (
    <div>
      获取id:{searchParams.get('id')}
      获取sort:{searchParams.get('sort')}
    </div>
  );
};

export default File;

3. state传参

1.定义路由

arduino 复制代码
{
  path: "/file",
  element: <File />,
},
  1. 编程式传参
xml 复制代码
<NavLink to="/file" state={{ id: 1 }} end>  file</NavLink>
  1. 命令式传参
css 复制代码
<button onClick={() => navigation("/file", { state: { id: "2" } })}>  file</button>
  1. 获取参数
javascript 复制代码
import { useLocation } from "react-router-dom";
const File = () => {
  const { state } = useLocation();
  return <div>{state.id}</div>;
};

export default File;

特点:参数不会显示在路径上

七、错误处理

在路由组件加载过程中发生错误时展示的元素

  1. 新建pages/errorBoundary.tsx
javascript 复制代码
import { useRouteError } from 'react-router-dom';

const ErrorBoundary = () => {
  const error = useRouteError();
  //错误信息,可用来错误上报
  console.log(error);
  return <>错误页面</>;
};

export default ErrorBoundary;
  1. 修改router/index.tsx
javascript 复制代码
import ErrorBoundary from "../pages/errorBoundary";

const routes = [
  //...
  {
    element: <Home />,
    errorElement: <ErrorBoundary />, //挂载到父路由上
  },
]
  1. 修改pages/router.tsx,使其报错
typescript 复制代码
import { useNavigate } from "react-router-dom";

const obj: any = {
  a: "2",
};

const User = () => {
  const navigation = useNavigate();
  return (
    <div>
      {/* 报错:因为取不到c属性 */}
      {obj.b.c}
      user
      <button onClick={() => navigation("/manage")}>manage</button>
    </div>
  );
};

export default User;

访问/user时,可以看到原先的user页面内容被替换为错误页面

提示:如果路由没有配置errorElement,则错误将冒泡到最近的父路由上

八、重定向

情景:当没有权限时,重定向到登录页

修改pages/manage.tsx

javascript 复制代码
import { Navigate } from 'react-router-dom';

const Manage = () => {
  if (!localStorage.getItem('token')) {
    return <Navigate to="/login" replace={true} />;
  }

  return <div>manage</div>;
};

export default Manage;

replace={true}:进行重定向

九、loader,action

loader:在路由导航完成之前执行,类似于vue router的路由前置守卫

action:使用react-router-dom提供的Form表单,当表单提交时action会被触发

loader与action都是V6版本新增的内容,实际使用场景并不多,这里不再详细阐述。

相关推荐
黄同学real39 分钟前
常见的 CSS 知识点整理
前端·css
oMMh1 小时前
使用C# ASP.NET创建一个可以由服务端推送信息至客户端的WEB应用(1)
前端·c#·asp.net
Huazzi.1 小时前
打造惊艳的渐变色下划线动画:CSS实现详解
前端·css
北方之mini鱼1 小时前
使用Construct开发一个HTML5小游戏究竟需要多长时间?
前端·html·html5
佬乔1 小时前
JWT-验证
java·服务器·前端
网络大镖客1 小时前
JavaScript高级进阶(五)
开发语言·前端·javascript
星空寻流年2 小时前
css3伸缩盒模型第一章(主轴以及伸缩盒模型)
前端·css·css3
酷爱码3 小时前
好看的个人主页HTML源码分享
前端·html
三思而后行,慎承诺3 小时前
react的fiber 用法
前端·javascript·react.js
Deepsleep.3 小时前
前端性能优化面试回答技巧
前端·面试·性能优化