告别“单页”寂寞:React Router 带你飞,页面跳转像滑滑梯! 🎢

引言

大家好,我是你们的程序猿老朋友,今天咱们来聊聊 React 开发中不可或缺的灵魂伴侣------React Router

🧐 为啥需要路由?

想象一下,如果你的网站只有一个页面,所有内容都挤在一起,那会是怎样一种灾难?就像把所有水果都塞进一个袋子,西瓜压坏了苹果,香蕉被挤成了泥...😱 为了让我们的应用井井有条,结构清晰,路由应运而生!它就像一个交通指挥官,根据不同的 URL,把用户带到不同的页面。

小 Tips: 路由驱动应用,就像一个精密的时钟,每个齿轮的转动都至关重要。

🛠️ React Router:组件化路由的扛把子

就像 React 是组件化的王者,React Router 也秉承了这一优良传统。它把路由的概念也组件化了,让我们的代码更加易读、易维护。

1. 安装 "全家桶" 必备:

npm install react-router-dom

首先,我们需要安装 react-router-dom 这个包,它包含了我们实现路由所需要的一切。

2. 路由定义大舞台:router/index.jsx

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

    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

    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)

    jsx 复制代码
    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 的 mountedupdated 的结合体。

    • 第二个参数(可选):依赖项数组,类似 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

    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 类名,方便你设置高亮样式。

      NavLinka 标签的区别: NavLink 会阻止页面刷新,通过 React Router 实现页面跳转,而 a 标签会刷新整个页面。NavLink 就像一辆飞速的跑车,而 a 标签则是一辆略显笨拙的老爷车。 🚗

      NavLink 的优势:

      • 不会刷新页面,提高用户体验。
      • 支持高亮样式,方便用户知道当前所在页面。

小 Tips: 页面组件是你的舞台,路由帮你把观众带到这里,而 Outlet 则是你表演的焦点! 🎭

4. 嵌套路由:post 文件夹下的内容,这一部分你可以当成我们要进行一个更深的页面跳转

jsx 复制代码
// 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 应用的利器,它可以让你轻松实现页面跳转和嵌套路由,让你的应用焕发新的生机!

如果你觉得这篇文章对你有帮助,别忘了点赞、分享和收藏哦!

下次见! 👋

相关推荐
半点寒12W4 分钟前
css3网格布局
前端·css·css3
wu_yi_min3 小时前
Spring Web MVC综合案例
前端·spring·mvc
浪浪山小白兔3 小时前
HTML 中的 Window 和 Document 介绍
前端·javascript·html
itwlz3 小时前
npm发布工具包+使用
前端·javascript·npm
md_10084 小时前
Flutter ListView进阶:如何实现根据索引值滚动到列表特定位置
前端·javascript·flutter
灵感__idea4 小时前
Vuejs技术内幕:数据响应式之2.x版
前端·vue.js·源码阅读
癞皮狗不赖皮4 小时前
WEB攻防-通用漏洞_XSS跨站_绕过修复_http_only_CSP_标签符号
前端·web安全·网络安全·xss
Koi慢热4 小时前
被动扫描和主动扫描的区别
java·前端·网络安全·github·系统安全
dgw26486338095 小时前
HTML练习-校园官网首页面
前端·css·html
卿言卿语5 小时前
第二章:CSS的复合选择器
前端·css·html