当前位置: 首页 > article >正文

React 路由导航与传参详解

随着单页面应用(SPA)已经成为主流。React 作为最流行的前端框架之一,提供了强大的路由管理工具 react-router-dom,帮助开发者轻松实现页面导航和传参。本文将详细介绍如何使用 react-router-dom 构建路由导航、传参以及嵌套路由的实现。

1. 构建路由导航

1.1 创建路由实例

在 React 项目中,通常会在 src 目录下创建一个 router 文件夹来管理路由。我们可以使用 react-router-dom 提供的 createBrowserRoutercreateHashRouter 方法来创建路由实例。

  • createBrowserRouter:使用 HTML5 的 history API 来实现路由,URL 看起来更干净,例如:http://example.com/home
  • createHashRouter:使用 URL 的 hash 部分来实现路由,例如:http://example.com/#/home
import { createBrowserRouter } from 'react-router-dom';

const router = createBrowserRouter([
  {
    path: '/',
    element: <Home />,
  },
  {
    path: '/login',
    element: <Login />,
  },
  {
    path: '/article',
    element: <Article />,
  },
]);

export default router;

1.2 嵌套路由

react-router-dom 中,可以通过 children 属性来配置嵌套路由。嵌套路由允许我们在父路由下定义子路由,从而实现更复杂的页面结构。

const router = createBrowserRouter([
  {
    path: '/',
    element: <Layout />,
    children: [
      {
        path: 'home',
        element: <Home />,
      },
      {
        path: 'about',
        element: <About />,
      },
    ],
  },
]);

1.3 路由导航

在 React 中,有两种主要的方式来实现路由导航:声明式导航编程式导航

1.3.1 声明式导航

使用 <Link> 组件可以实现声明式导航。<Link> 组件会渲染成一个 <a> 标签,点击后会跳转到指定的路由。

import { Link } from 'react-router-dom';

const Login = () => {
  return (
    <div>
      <h1>登录页</h1>
      <Link to="/article">文章页</Link>
    </div>
  );
};

- 思考:为啥不用a标签?

  • a标签每次全部刷新页面,并且需要重新挂载组件,对状态(useState登)需要重置;
    每次导航都会重新加载所有资源(如 JavaScript、CSS 等),即使这些资源在前一个页面已经加载过;
    无法直接支持动态路由(如 /user/:id);
  • link标签正好弥补上面缺陷,适合单页面Spa应用。
    自动与路由库(如 React Router)集成,支持浏览器的前进和后退功能,同时更新 URL 和历史记录;
    只有必要的部分(如新路由对应的组件)会被加载,减少了不必要的网络请求和资源消耗;
    点击 组件只会更新当前页面的部分内容(通常是路由对应的组件),而不会重新加载整个页面。这使得无缝地在不同页面之间切换
1.3.2 编程式导航

使用 useNavigate 钩子可以实现编程式导航。useNavigate 返回一个函数,调用该函数并传入目标路径即可实现导航。

import { useNavigate } from 'react-router-dom';

const Login = () => {
  const navigate = useNavigate();

  return (
    <div>
      <h1>登录页</h1>
      <button onClick={() => navigate('/article')}>文章页</button>
    </div>
  );
};

2. 路由传参

在 React 路由中,常见的传参方式有两种:searchParams 传参params 传参

2.1 searchParams 传参

searchParams 传参是通过 URL 的查询字符串来传递参数的。我们可以使用 useSearchParams 钩子来获取和设置查询参数。

import { useNavigate } from 'react-router-dom';

const Login = () => {
  const navigate = useNavigate();

  return (
    <div>
      <h1>登录页</h1>
      <button onClick={() => navigate('/article?id=1&name=zs')}>
        searchParams 传参
      </button>
    </div>
  );
};

在目标组件中,可以使用 useSearchParams 来获取传递的参数:

import { useSearchParams } from 'react-router-dom';

const Article = () => {
  const [searchParams] = useSearchParams();
  const id = searchParams.get('id');
  const name = searchParams.get('name');

  return (
    <div>
      <h1>文章页</h1>
      <p>ID: {id}</p>
      <p>Name: {name}</p>
    </div>
  );
};

2.2 params 传参

params 传参是通过 URL 的动态段来传递参数的。首先需要在路由配置中定义动态段,然后在导航时传递参数。

2.2.1 路由配置
const router = createBrowserRouter([
  {
    path: '/article/:id/:name',
    element: <Article />,
  },
]);
2.2.2 导航传参
import { useNavigate } from 'react-router-dom';

const Login = () => {
  const navigate = useNavigate();

  return (
    <div>
      <h1>登录页</h1>
      <button onClick={() => navigate('/article/1001/jack')}>
        params 传参
      </button>
    </div>
  );
};
2.2.3 获取参数

在目标组件中,可以使用 useParams 钩子来获取传递的参数:

import { useParams } from 'react-router-dom';

const Article = () => {
  const { id, name } = useParams();

  return (
    <div>
      <h1>文章页</h1>
      <p>ID: {id}</p>
      <p>Name: {name}</p>
    </div>
  );
};

3. 嵌套路由与 <Outlet />

在嵌套路由中,父路由组件需要使用 <Outlet /> 组件作为子路由的占位符。当导航到子路由时,<Outlet /> 会被替换为对应的子路由组件。

import { Outlet } from 'react-router-dom';

const Layout = () => {
  return (
    <div>
      <h1>布局页</h1>
      <Outlet />
    </div>
  );
};

在路由配置中,Layout 组件作为父路由,HomeAbout 作为子路由:

const router = createBrowserRouter([
  {
    path: '/',
    element: <Layout />,
    children: [
      {
        path: 'home',
        element: <Home />,
      },
      {
        path: 'about',
        element: <About />,
      },
    ],
  },
]);

4. 重定向与 redirect 参数

在某些场景下,用户可能会尝试访问需要登录的页面,但此时用户尚未登录。为了提升用户体验,我们可以在用户登录后将其重定向回原本想要访问的页面。为了实现这一功能,我们可以在 URL 中添加 redirect 查询参数,记录用户原本想要访问的页面。

4.1 添加 redirect 参数

在用户访问需要登录的页面时,我们可以通过编程式导航将用户重定向到登录页面,并在 URL 中添加 redirect 参数,记录原本要访问的页面。

import { useNavigate } from 'react-router-dom';

const ProtectedPage = () => {
  const navigate = useNavigate();

  const handleAccess = () => {
    const isLoggedIn = false; // 假设用户未登录
    if (!isLoggedIn) {
      navigate(`/login?redirect=${encodeURIComponent('/protected-page')}`);
    }
  };

  return (
    <div>
      <h1>受保护的页面</h1>
      <button onClick={handleAccess}>访问受保护页面</button>
    </div>
  );
};

4.2 登录后重定向

在登录页面中,我们可以通过 useSearchParams 获取 redirect 参数,并在用户成功登录后将其重定向回原本想要访问的页面。

import { useSearchParams, useNavigate } from 'react-router-dom';

const Login = () => {
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();
  const redirect = searchParams.get('redirect') || '/';

  const handleLogin = () => {
    // 假设登录成功
    navigate(redirect);
  };

  return (
    <div>
      <h1>登录页</h1>
      <button onClick={handleLogin}>登录</button>
    </div>
  );
};

总结

通过 react-router-dom,我们可以轻松实现 React 应用中的路由导航、传参以及嵌套路由。<Link>useNavigate 提供了灵活的导航方式,而 useSearchParamsuseParams 则帮助我们处理路由传参。<Outlet /> 组件为嵌套路由提供了便捷的占位符功能。此外,通过 redirect 参数,我们可以在用户登录后将其重定向回原本想要访问的页面,从而提升用户体验。掌握这些工具和技巧,能够帮助我们构建更加复杂和高效的单页面应用。


http://www.kler.cn/a/516294.html

相关文章:

  • 【前端】Hexo 建站指南
  • c语言(转义字符)
  • 后端的config包中的常用配置
  • 中国综合算力指数(2024年)报告汇总PDF洞察(附原数据表)
  • Vue中设置报错页面和“Uncaught runtime errors”弹窗关闭
  • Linux探秘坊-------5.git
  • 力扣hot100-->滑动窗口、贪心
  • Vue入门(Vue基本语法、axios、组件、事件分发)
  • Python自带模块实现屏幕像素高效操作
  • VUE对接deepseekAPI调用
  • 【LeetCode 刷题】二叉树-深度优先遍历
  • Chromium 132 编译指南 Mac 篇(二)- 安装 Xcode
  • WPF-系统资源
  • 豆包MarsCode:小C点菜问题
  • 左/右侧边栏布局(Semi design)
  • FPGA实现任意角度视频旋转(二)视频90度/270度无裁剪旋转
  • react antd点击table单元格文字下载指定的excel路径
  • Conmi的正确答案——Rider中引入WebView2包(C#)
  • Django 日志配置实战指南
  • .NET 9 微软官方推荐使用 Scalar 替代传统的 Swagger
  • 【项目初始化】自定义异常处理
  • 终极的复杂,是简单
  • PVE 虚拟机安装 Debian 无图形化界面服务器
  • 【后端开发】字节跳动青训营之Go语言进阶与依赖管理
  • Elementor Pro 3.27 汉化版 2100套模板 安装教程 wordpress主题中文编辑器插件免费下载
  • 缓存-Redis-数据结构-redis哪些数据结构是跳表实现的?