🤍 前端开发工程师、技术日更博主、已过CET6
🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1
🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》
🍚 蓝桥云课签约作者、上架课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》
💬 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
文章目录
一、背景与用途
在单页应用(SPA)中,用户界面的不同部分需要根据用户的操作(如点击链接)进行动态更新,而无需重新加载整个页面。React - Router就是为满足这种需求而设计的一个强大的路由库,它允许开发者在React应用中实现页面导航和视图切换。通过定义不同的路由路径和对应的组件,能够为用户提供流畅的多页面体验。
二、基本概念与语法
(一)安装与基本设置
- 安装React - Router
- 可以使用npm或yarn来安装React - Router。以npm为例,在项目目录下执行命令:
npm install react - router-dom
。
- 可以使用npm或yarn来安装React - Router。以npm为例,在项目目录下执行命令:
- 导入必要的组件
- 在使用React - Router的组件文件中,需要导入相关的组件。例如,最常用的
BrowserRouter
、Routes
和Route
组件:
import { BrowserRouter as Router, Routes, Route } from'react - router - dom';
BrowserRouter
(通常别名为Router
)用于包裹整个应用,它使用HTML5的history
API来处理路由。Routes
组件用于定义一组路由规则,Route
组件则用于定义单个路由。
- 在使用React - Router的组件文件中,需要导入相关的组件。例如,最常用的
(二)定义路由
-
基本路由定义
- 路由定义通常在应用的顶层组件或者路由模块中进行。例如,定义一个简单的路由,当用户访问
/
路径时显示Home
组件,访问/about
路径时显示About
组件:
const App = () => { return ( <Router> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </Router> ); };
- 这里,
path
属性指定了路由的路径,element
属性指定了当路径匹配时要渲染的React组件。
- 路由定义通常在应用的顶层组件或者路由模块中进行。例如,定义一个简单的路由,当用户访问
-
嵌套路由
- 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
组件。
- React - Router支持嵌套路由,这对于构建具有层次结构的应用非常有用。例如,在一个博客应用中,
(三)导航
-
使用
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会根据路径匹配并渲染相应的组件。
-
编程式导航
- 除了使用
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
返回一个函数,这个函数接受一个路径参数,用于在程序执行过程中触发导航。
- 除了使用
三、使用场景与示例
(一)多页面应用
- 简单的企业网站示例
- 假设要构建一个企业网站,包括首页、关于我们、产品展示和联系我们等页面。
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
组件在导航栏创建了各个页面的链接,Routes
和Route
组件定义了每个页面的路由路径和对应的组件。当用户点击导航链接时,会显示相应的页面内容。
(二)具有授权保护的路由
- 用户登录与授权示例
- 考虑一个应用,其中某些页面需要用户登录后才能访问。可以使用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
进行保护。
四、注意事项与常见错误
(一)路径匹配的精确性
- 问题描述
- 在定义路由路径时,需要注意路径匹配的精确性。如果路径定义不精确,可能会导致意外的组件渲染。例如,当定义一个
/about
路径的路由和一个/about - us
路径的路由时,如果不小心,可能会出现两个路由都匹配/about - us
路径的情况。
- 在定义路由路径时,需要注意路径匹配的精确性。如果路径定义不精确,可能会导致意外的组件渲染。例如,当定义一个
- 解决方法
- 可以使用
exact
属性来确保路径的精确匹配。在旧版本的React - Router中,Route
组件默认是模糊匹配的。例如:
<Route exact path="/about" element={<About />} />
- 这样,只有当路径完全是
/about
时,才会渲染About
组件。不过在React - Router v6中,Route
组件默认是精确匹配的,所以在使用新版本时要注意这一变化。
- 可以使用
(二)相对路径与绝对路径
- 问题描述
- 在使用
Link
组件或者编程式导航时,路径的相对和绝对表示可能会引起混淆。如果使用不当,可能会导致导航到错误的路径。
- 在使用
- 解决方法
- 要明确路径是相对路径还是绝对路径。在
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
时要注意路径的表示方式。
- 要明确路径是相对路径还是绝对路径。在
(三)路由参数
- 问题描述
- 当使用路由参数(例如,在博客应用中,根据文章ID来显示不同的文章)时,需要正确地获取和使用这些参数。如果参数获取或使用不当,可能会导致无法正确显示相关内容。
- 解决方法
- 在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
参数,然后可以根据这个参数来获取和显示相应的文章内容。
- 在React - Router v6中,可以使用