深入理解React - Router路由:你需要知道的一切

在这里插入图片描述

🤍 前端开发工程师、技术日更博主、已过CET6
🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1
🕠 牛客高级专题作者、打造专栏《前端面试必备》《2024面试高频手撕题》
🍚 蓝桥云课签约作者、上架课程《Vue.js 和 Egg.js 开发企业级健康管理项目》《带你从入门到实战全面掌握 uni-app》
💬 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

一、背景与用途

在单页应用(SPA)中,用户界面的不同部分需要根据用户的操作(如点击链接)进行动态更新,而无需重新加载整个页面。React - Router就是为满足这种需求而设计的一个强大的路由库,它允许开发者在React应用中实现页面导航和视图切换。通过定义不同的路由路径和对应的组件,能够为用户提供流畅的多页面体验。

二、基本概念与语法

(一)安装与基本设置

  1. 安装React - Router
    • 可以使用npm或yarn来安装React - Router。以npm为例,在项目目录下执行命令:npm install react - router-dom
  2. 导入必要的组件
    • 在使用React - Router的组件文件中,需要导入相关的组件。例如,最常用的BrowserRouterRoutesRoute组件:
    import { BrowserRouter as Router, Routes, Route } from'react - router - dom';
    
    • BrowserRouter(通常别名为Router)用于包裹整个应用,它使用HTML5的history API来处理路由。Routes组件用于定义一组路由规则,Route组件则用于定义单个路由。

(二)定义路由

  1. 基本路由定义

    • 路由定义通常在应用的顶层组件或者路由模块中进行。例如,定义一个简单的路由,当用户访问/路径时显示Home组件,访问/about路径时显示About组件:
    const App = () => {
      return (
        <Router>
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/about" element={<About />} />
          </Routes>
        </Router>
      );
    };
    
    • 这里,path属性指定了路由的路径,element属性指定了当路径匹配时要渲染的React组件。
  2. 嵌套路由

    • React - Router支持嵌套路由,这对于构建具有层次结构的应用非常有用。例如,在一个博客应用中,/blog路径下可能有多个子路径,如/blog/post1/blog/post2等。
    const Blog = () => {
      return (
        <div>
          <h1>Blog</h1>
          <Routes>
            <Route path="/post1" element={<Post1 />} />
            <Route path="/post2" element={<Post2 />} />
          </Routes>
        </div>
      );
    };
    
    const App = () => {
      return (
        <Router>
          <Routes>
            <Route path="/blog" element={<Blog />} />
          </Routes>
        </Router>
      );
    };
    
    • 在这个例子中,Blog组件内部定义了嵌套的路由。当用户访问/blog/post1时,首先匹配/blog路径,渲染Blog组件,然后在Blog组件内部匹配/post1路径,渲染Post1组件。

(三)导航

  1. 使用Link组件进行导航

    • Link组件是React - Router提供的用于在应用内部进行导航的组件,它会渲染为一个<a>标签,但不会引起整个页面的重新加载。例如,在Home组件中创建一个链接到About组件的导航:
    import { Link } from'react - router - dom';
    
    const Home = () => {
      return (
        <div>
          <h1>Home</h1>
          <Link to="/about">Go to About</Link>
        </div>
      );
    };
    
    • 这里,Link组件的to属性指定了目标路由的路径。当用户点击这个链接时,React - Router会根据路径匹配并渲染相应的组件。
  2. 编程式导航

    • 除了使用Link组件,还可以通过useNavigate Hook进行编程式导航。例如,在一个按钮的点击事件处理函数中进行导航:
    import React from 'react';
    import { useNavigate } from'react - router - dom';
    
    const SomeComponent = () => {
      const navigate = useNavigate();
      const handleClick = () => {
        navigate('/some - other - path');
      };
      return (
        <div>
          <button onClick={handleClick}>Go to Some Other Path</button>
        </div>
      );
    };
    
    • useNavigate返回一个函数,这个函数接受一个路径参数,用于在程序执行过程中触发导航。

三、使用场景与示例

(一)多页面应用

  1. 简单的企业网站示例
    • 假设要构建一个企业网站,包括首页、关于我们、产品展示和联系我们等页面。
    import React from 'react';
    import { BrowserRouter as Router, Routes, Route, Link } from'react - router - dom';
    
    const Home = () => {
      return (
        <div>
          <h1>Home</h1>
          <p>Welcome to our website!</p>
        </div>
      );
    };
    
    const About = () => {
      return (
        <div>
          <h1>About Us</h1>
          <p>We are a company dedicated to...</p>
        </div>
      );
    };
    
    const Products = () => {
      return (
        <div>
          <h1>Our Products</h1>
          <p>Here are our amazing products...</p>
        </div>
      );
    };
    
    const Contact = () => {
      return (
        <div>
          <h1>Contact Us</h1>
          <p>You can reach us at...</p>
        </div>
      );
    };
    
    const App = () => {
      return (
        <Router>
          <nav>
            <Link to="/">Home</Link>
            <Link to="/about">About</Link>
            <Link to="/products">Products</Link>
            <Link to="/contact">Contact</Link>
          </nav>
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/about" element={<About />} />
            <Route path="/products" element={<Products />} />
            <Route path="/contact" element={<Contact />} />
          </Routes>
        </Router>
      );
    };
    
    • 在这个例子中,通过Link组件在导航栏创建了各个页面的链接,RoutesRoute组件定义了每个页面的路由路径和对应的组件。当用户点击导航链接时,会显示相应的页面内容。

(二)具有授权保护的路由

  1. 用户登录与授权示例
    • 考虑一个应用,其中某些页面需要用户登录后才能访问。可以使用React - Router来实现路由保护。
    import React, { useState } from 'react';
    import { BrowserRouter as Router, Routes, Route, Link, Navigate } from'react - router - dom';
    
    const Login = () => {
      const [username, setUsername] = useState('');
      const [password, setPassword] = useState('');
      const handleLogin = () => {
        // 假设这里是简单的验证逻辑,实际应用中可能会发送API请求
        if (username === 'admin' && password === 'password') {
          localStorage.setItem('isLoggedIn', 'true');
        }
      };
      return (
        <div>
          <h1>Login</h1>
          <input
            type="text"
            placeholder="Username"
            value={username}
            onChange={(e) => setUsername(e.target.value)}
          />
          <input
            type="password"
            placeholder="Password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
          />
          <button onClick={handleLogin}>Login</button>
        </div>
      );
    };
    
    const ProtectedRoute = ({ element }) => {
      const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true';
      return isLoggedIn? element : <Navigate to="/login" />;
    };
    
    const Dashboard = () => {
      return (
        <div>
          <h1>Dashboard</h1>
          <p>Welcome to your dashboard!</p>
        </div>
      );
    };
    
    const App = () => {
      return (
        <Router>
          <Routes>
            <Route path="/login" element={<Login />} />
            <Route
              path="/dashboard"
              element={<ProtectedRoute element={<Dashboard />} />}
            />
          </Routes>
        </Router>
      );
    };
    
    • 在这个示例中,定义了一个Login组件用于用户登录。ProtectedRoute是一个自定义的组件,用于检查用户是否登录(通过检查localStorage中的isLoggedIn项)。如果用户已登录,就渲染传入的element(在这个例子中是Dashboard组件),否则将用户导航到/login路径。Dashboard组件是一个需要授权才能访问的页面,通过ProtectedRoute进行保护。

四、注意事项与常见错误

(一)路径匹配的精确性

  1. 问题描述
    • 在定义路由路径时,需要注意路径匹配的精确性。如果路径定义不精确,可能会导致意外的组件渲染。例如,当定义一个/about路径的路由和一个/about - us路径的路由时,如果不小心,可能会出现两个路由都匹配/about - us路径的情况。
  2. 解决方法
    • 可以使用exact属性来确保路径的精确匹配。在旧版本的React - Router中,Route组件默认是模糊匹配的。例如:
    <Route exact path="/about" element={<About />} />
    
    • 这样,只有当路径完全是/about时,才会渲染About组件。不过在React - Router v6中,Route组件默认是精确匹配的,所以在使用新版本时要注意这一变化。

(二)相对路径与绝对路径

  1. 问题描述
    • 在使用Link组件或者编程式导航时,路径的相对和绝对表示可能会引起混淆。如果使用不当,可能会导致导航到错误的路径。
  2. 解决方法
    • 要明确路径是相对路径还是绝对路径。在Link组件的to属性中,以/开头的路径是绝对路径,相对于应用的根路径;没有/开头的路径是相对路径,相对于当前路由的路径。例如,在/blog路径下的一个组件中,如果要导航到/blog/post1,可以使用相对路径post1或者绝对路径/blog/post1
    // 相对路径
    <Link to="post1">Go to Post 1</Link>
    // 绝对路径
    <Link to="/blog/post1">Go to Post 1</Link>
    
    • 在编程式导航中也是同样的道理,使用useNavigate时要注意路径的表示方式。

(三)路由参数

  1. 问题描述
    • 当使用路由参数(例如,在博客应用中,根据文章ID来显示不同的文章)时,需要正确地获取和使用这些参数。如果参数获取或使用不当,可能会导致无法正确显示相关内容。
  2. 解决方法
    • 在React - Router v6中,可以使用useParams Hook来获取路由参数。例如,定义一个路由来显示具有特定ID的博客文章:
    const BlogPost = () => {
      const { postId } = useParams();
      // 根据postId获取并显示文章内容,可能需要发送API请求等操作
      return (
        <div>
          <h1>Blog Post with ID {postId}</h1>
        </div>
      );
    };
    
    const App = () => {
      return (
        <Router>
          <Routes>
            <Route path="/blog/:postId" element={<BlogPost />} />
          </Routes>
        </Router>
      );
    };
    
    • 这里,:postId在路由路径中表示一个参数。在BlogPost组件中,通过useParams Hook获取postId参数,然后可以根据这个参数来获取和显示相应的文章内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿珊和她的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值