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版本新增的内容,实际使用场景并不多,这里不再详细阐述。

相关推荐
旧曲重听114 分钟前
最快实现的前端灰度方案
前端·程序人生·状态模式
默默coding的程序猿23 分钟前
3.前端和后端参数不一致,后端接不到数据的解决方案
java·前端·spring·ssm·springboot·idea·springcloud
夏梦春蝉29 分钟前
ES6从入门到精通:常用知识点
前端·javascript·es6
马特说32 分钟前
React金融数据分析应用性能优化实战:借助AI辅助解决18万数据量栈溢出Bug
react.js·金融·数据分析
归于尽35 分钟前
useEffect玩转React Hooks生命周期
前端·react.js
G等你下课36 分钟前
React useEffect 详解与运用
前端·react.js
我想说一句37 分钟前
当饼干遇上代码:一场HTTP与Cookie的奇幻漂流 🍪🌊
前端·javascript
funnycoffee12338 分钟前
Huawei 6730 Switch software upgrade example版本升级
java·前端·华为
小鱼小鱼干40 分钟前
【Tauri】Tauri中Channel的使用
前端
拾光拾趣录42 分钟前
CSS全面指南:从基础布局到高级技巧与实践
前端·css