大家好,我是你们的程序猿老朋友,今天咱们来聊聊 React 开发中不可或缺的灵魂伴侣——React Router!
为啥需要路由?
想象一下,如果你的网站只有一个页面,所有内容都挤在一起,那会是怎样一种灾难?就像把所有水果都塞进一个袋子,西瓜压坏了苹果,香蕉被挤成了泥… 为了让我们的应用井井有条,结构清晰,路由应运而生!它就像一个交通指挥官,根据不同的 URL,把用户带到不同的页面。
小 Tips: 路由驱动应用,就像一个精密的时钟,每个齿轮的转动都至关重要。
React Router:组件化路由的扛把子
就像 React 是组件化的王者,React Router 也秉承了这一优良传统。它把路由的概念也组件化了,让我们的代码更加易读、易维护。
1. 安装 “全家桶” 必备:
npm install react-router-dom
首先,我们需要安装 react-router-dom 这个包,它包含了我们实现路由所需要的一切。
2. 路由定义大舞台:router/index.jsx
import {
BrowserRouter,
Route,
Routes,
} from 'react-router-dom'
import App from '../App'
import About from '../pages/About.jsx'
import Home from '../pages/Home.jsx'
import NotFound from '../pages/NotFound.jsx'
import { postRouter } from '../pages/post/postRouter.jsx'
const AppRouter = () => {
return (
<BrowserRouter>
<Routes>
<Route path='/' element={<App />} >
<Route index element={<Home />} />
<Route path='about' element={<About />} />
<Route path="posts/*" element={postRouter} />
<Route path='*' element={<NotFound />} />
</Route>
</Routes>
</BrowserRouter>
)
}
export default AppRouter
<BrowserRouter>: 这是路由的“地基”,它能让你的应用支持 HTML5 的 pushState API,从而实现漂亮的 URL 切换。
<Routes>: 它就像一个“路由匹配器”,它会遍历 <Route> 标签,找到与当前 URL 匹配的路由,并渲染对应的组件。
<Route>: 每一个 <Route> 标签都代表一条路由规则。path 属性定义了 URL 的路径,element 属性指定了要渲染的组件。
index 属性: 当父路由路径和当前路由路径相同时,渲染此属性的组件。
path="*" : 通配符,当所有路由都不匹配时,渲染此路由组件,通常用于渲染 404 页面。
嵌套路由: 在父路由 <Route> 中再嵌套 <Route>,实现父子组件的嵌套渲染,如示例中 posts 就是嵌套路由。
小 Tips: BrowserRouter 就像你的大船,<Routes> 是你的航线图,<Route> 是你的一个个港口,带你抵达想去的地方。
3. 页面组件:你的内容展示区
About.jsx
import { useEffect } from "react"
import { Link } from 'react-router-dom'
const About = () => {
useEffect(() => {
document.title = 'About'
}, [])
return (
<div>
<h1>About</h1>
<Link to='/'>回到首页</Link>
</div>
)
}
export default About
useEffect: 它是一个 React Hooks,我们用来在组件挂载后执行一些操作,比如在这里,我们修改了页面的标题。
Link: 这是 React Router 提供的导航组件,它会生成一个 <a> 标签,点击它会触发路由切换,注意这里和普通的 <a> 标签不一样,他不会刷新页面,这也是SPA应用的优点。
Home.jsx
import { useEffect } from "react"
const Home = () => {
useEffect(() => {
document.title = 'Home'
}, [])
return (
<div>
<h1>Home</h1>
<div>你好</div>
</div>
)
}
export default Home
NotFound.jsx (这一部分会有点复杂o)
import { useState, useEffect } from "react"
const NotFound = () => {
const [count, setCount] = useState(0)
useEffect(() => {
console.log('title执行了');
document.title = 'Not Found'
return () => {
console.log('title卸载了');
}
}, [])
const add = () => {
setCount(count + 1)
}
useEffect(() => {
console.log('count更新了');
}, [count])
return (
<div>
<h1 onClick={add}>404</h1>
</div>
)
}
export default NotFound
useState: 组件的状态管理,像 Vue 的 data!
useState 就像一个简易的记事本,用来记录组件的数据。例如,const [count, setCount] = useState(0) 就相当于 Vue 的 data 中定义了 count: 0,你可以用 setCount 更新 count 的值。
useEffect: 副作用处理,React 的生命周期钩子!
第一个参数:副作用函数,类似 Vue 的 mounted + updated!
useEffect(() => { /* ... */ }) 里的函数会在组件首次渲染后执行,也会在更新后执行,相当于 Vue 的 mounted 和 updated 的结合体。
第二个参数(可选):依赖项数组,类似 Vue 的 watch!
useEffect(() => { /* ... */ }, [count]) 表示只有 count 变化时,副作用函数才会执行,相当于 Vue 的 watch 监听 count 的变化。
返回值(可选):清理函数,类似 Vue 的 beforeUnmount!
useEffect(() => { return () => { /* ... */ } }) 返回的函数会在组件卸载前执行,用于清理副作用,类似于 Vue 的 beforeUnmount 钩子。
小小总结一下:
useState:管理组件状态,类似 Vue 的 data。
useEffect:处理副作用,类似 Vue 的生命周期钩子:
无第二个参数,类似 mounted + updated。
有第二个参数,类似 watch。
返回值,类似 beforeUnmount。
主页面 App.jsx
import './App.css'
import {
Outlet,
NavLink
} from "react-router-dom"
function App() {
return (
<>
<header>
<nav>
<NavLink to='/'>Home</NavLink>
<NavLink to='/about'>About</NavLink>
</nav>
</header>
<Outlet />
</>
)
}
export default App
Outlet: 它就像一个“占位符”,用来渲染嵌套路由的子组件,在这里,他用来渲染Home和About组件。
NavLink: 它是 Link 的升级版,当它对应的路由被激活时,会自动添加 active 类名,方便你设置高亮样式。
NavLink 和 a 标签的区别: NavLink 会阻止页面刷新,通过 React Router 实现页面跳转,而 a 标签会刷新整个页面。NavLink 就像一辆飞速的跑车,而 a 标签则是一辆略显笨拙的老爷车。
NavLink 的优势:
不会刷新页面,提高用户体验。
支持高亮样式,方便用户知道当前所在页面。
小 Tips: 页面组件是你的舞台,路由帮你把观众带到这里,而 Outlet 则是你表演的焦点!
4. 嵌套路由:post 文件夹下的内容,这一部分你可以当成我们要进行一个更深的页面跳转
// postRouter.jsx
import {
Route, Routes
} from "react-router-dom";
import PostIndex from './Post-Index.jsx';
import PostShow from './Post-Show.jsx';
export const postRouter = (
<Routes>
<Route path='' element={<PostIndex />} />
<Route path=':postid' element={<PostShow />} />
</Routes>
)
// Post-Index.jsx
const PostIndex = () => {
return (
<div>
<h1>PostIndex</h1>
</div>
)
}
export default PostIndex
// Post-Show.jsx
import { useEffect } from "react"
import { useParams } from "react-router-dom"
const PostShow = () => {
const { postid } = useParams()
useEffect(() => {
document.title = `Post-${postid}`
}, [])
return (
<div>
<h1>PostShow</h1>
</div>
)
}
export default PostShow
useParams: 这是一个 React Router Hooks,用来获取路由参数,在这里,我们用它来获取动态的 postid。(注意一下哦这个参数的名字要和动态路由(:postid)的名字一样哦)
小 Tips: 嵌套路由就像俄罗斯套娃,一层套一层,让你的应用更加灵活和模块化。
总结
好啦,关于 React Router 的精彩旅程就先到这里啦!希望这篇博客能帮助你更好地理解 React Router 的原理和用法。记住,React Router 是你构建复杂 React 应用的利器,它可以让你轻松实现页面跳转和嵌套路由,让你的应用焕发新的生机!
如果你觉得这篇文章对你有帮助,别忘了点赞、分享和收藏哦!
作者:answerball
链接:https://juejin.cn