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
js 复制代码
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 属性来配置嵌套路由。嵌套路由允许我们在父路由下定义子路由,从而实现更复杂的页面结构。

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

1.3 路由导航

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

1.3.1 声明式导航

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

js 复制代码
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 返回一个函数,调用该函数并传入目标路径即可实现导航。

js 复制代码
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 钩子来获取和设置查询参数。

js 复制代码
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 来获取传递的参数:

js 复制代码
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 路由配置
js 复制代码
const router = createBrowserRouter([
  {
    path: '/article/:id/:name',
    element: <Article />,
  },
]);
2.2.2 导航传参
js 复制代码
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 钩子来获取传递的参数:

js 复制代码
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 /> 会被替换为对应的子路由组件。

js 复制代码
import { Outlet } from 'react-router-dom';

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

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

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

4. 重定向与 redirect 参数

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

4.1 添加 redirect 参数

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

js 复制代码
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 参数,并在用户成功登录后将其重定向回原本想要访问的页面。

js 复制代码
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 参数,我们可以在用户登录后将其重定向回原本想要访问的页面,从而提升用户体验。掌握这些工具和技巧,能够帮助我们构建更加复杂和高效的单页面应用。

相关推荐
264玫瑰资源库9 分钟前
问道数码兽 怀旧剧情回合手游源码搭建教程(反查重优化版)
java·开发语言·前端·游戏
喝拿铁写前端20 分钟前
从圣经Babel到现代编译器:没开玩笑,普通程序员也能写出自己的编译器!
前端·架构·前端框架
HED26 分钟前
VUE项目发版后用户访问的仍然是旧页面?原因和解决方案都在这啦!
前端·vue.js
拉不动的猪1 小时前
前端自做埋点,我们应该要注意的几个问题
前端·javascript·面试
王景程1 小时前
如何测试短信接口
java·服务器·前端
安冬的码畜日常1 小时前
【AI 加持下的 Python 编程实战 2_10】DIY 拓展:从扫雷小游戏开发再探问题分解与 AI 代码调试能力(中)
开发语言·前端·人工智能·ai·扫雷游戏·ai辅助编程·辅助编程
小杨升级打怪中1 小时前
前端面经-JS篇(三)--事件、性能优化、防抖与节流
前端·javascript·xss
清风细雨_林木木1 小时前
Vue开发网站会有“#”原因是前端路由使用了 Hash 模式
前端·vue.js·哈希算法
鸿蒙布道师2 小时前
OpenAI为何觊觎Chrome?AI时代浏览器争夺战背后的深层逻辑
前端·人工智能·chrome·深度学习·opencv·自然语言处理·chatgpt
袈裟和尚2 小时前
如何在安卓平板上下载安装Google Chrome【轻松安装】
前端·chrome·电脑