最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React路由監(jiān)聽(tīng)/跳轉(zhuǎn)/守衛(wèi)的完整指南

 更新時(shí)間:2026年03月24日 08:26:48   作者:發(fā)現(xiàn)一只大呆瓜  
React Router 是 React 單頁(yè)應(yīng)用的核心路由庫(kù),除了基礎(chǔ)的路由配置,日常開(kāi)發(fā)中還會(huì)高頻用到路由監(jiān)聽(tīng)、編程式跳轉(zhuǎn)、路由守衛(wèi)等進(jìn)階功能,本文從實(shí)戰(zhàn)角度拆解這三大核心能力,需要的朋友可以參考下

前言

React Router 是 React 單頁(yè)應(yīng)用的核心路由庫(kù),除了基礎(chǔ)的路由配置,日常開(kāi)發(fā)中還會(huì)高頻用到路由監(jiān)聽(tīng)、編程式跳轉(zhuǎn)、路由守衛(wèi)等進(jìn)階功能。本文從實(shí)戰(zhàn)角度拆解這三大核心能力,涵蓋實(shí)現(xiàn)方式、場(chǎng)景對(duì)比、避坑要點(diǎn),基于 React Router v6+ 版本(主流穩(wěn)定版)講解,新手也能快速落地!

一、 路由監(jiān)聽(tīng):如何捕捉 URL 的變化?

在 React 中,React 監(jiān)聽(tīng)路由變化的本質(zhì)是監(jiān)聽(tīng) URL 相關(guān)屬性(pathname/search/params 等)的變化,觸發(fā)自定義回調(diào)函數(shù)。以下是 3 種常用實(shí)現(xiàn)方式:

1. 核心方案:useLocation+useEffect

這是最通用的監(jiān)聽(tīng)方式。通過(guò) useLocation 獲取當(dāng)前路由完整信息(pathname/search/state 等),結(jié)合 useEffect 監(jiān)聽(tīng) location 對(duì)象變化,觸發(fā)回調(diào)函數(shù)。

import { useLocation } from 'react-router-dom';
import { useEffect } from 'react';

const App = () => {
  const location = useLocation();

  useEffect(() => {
    // 每次路由切換時(shí)執(zhí)行
    console.log('當(dāng)前路徑:', location.pathname);
    console.log('搜索參數(shù):', location.search);
  }, [location]); 
};

2. 精準(zhǔn)監(jiān)聽(tīng):useParams與useSearchParams

如果你只關(guān)心某個(gè)特定的動(dòng)態(tài)參數(shù)(如 id),直接監(jiān)聽(tīng)參數(shù)對(duì)象會(huì)更高效。

  • useParams:監(jiān)聽(tīng)動(dòng)態(tài)路由參數(shù)(如 /user/:id 中的 id);
  • useSearchParams:監(jiān)聽(tīng) URL 搜索參數(shù)(如 ?page=1&size=10);
  • 適用場(chǎng)景:
    • 僅關(guān)注動(dòng)態(tài)路由參數(shù)或搜索參數(shù)變化的場(chǎng)景(如詳情頁(yè) ID 切換、列表頁(yè)分頁(yè)參數(shù)變化)。

3.監(jiān)聽(tīng)原生路由事件(不推薦)

  • 通過(guò) window.addEventListener 監(jiān)聽(tīng) popstate(History 模式)或 hashchange(Hash 模式)事件,直接捕獲 URL 變化。
  • 缺點(diǎn):React Router 已封裝原生事件,手動(dòng)監(jiān)聽(tīng)易出現(xiàn)重復(fù)觸發(fā)、狀態(tài)不一致問(wèn)題,僅建議特殊場(chǎng)景(如兼容老代碼)使用。

二、 路由跳轉(zhuǎn)

React Router 提供多種跳轉(zhuǎn)方式,適配「點(diǎn)擊跳轉(zhuǎn)」「編程式跳轉(zhuǎn)」「導(dǎo)航欄高亮」等不同場(chǎng)景:

1. 聲明式導(dǎo)航:<Link>與<NavLink>(最常用)

<Link> :基礎(chǔ)跳轉(zhuǎn),React Router 核心跳轉(zhuǎn)組件,替代原生 <a> 標(biāo)簽(避免頁(yè)面刷新),核心屬性如下:

  • to:必傳,目標(biāo)路徑(支持字符串 / 對(duì)象格式);
  • replace:默認(rèn) false(新增歷史記錄),true 則替換當(dāng)前記錄(跳轉(zhuǎn)后無(wú)法回退);
  • state:傳遞自定義狀態(tài)(不顯示在 URL 中,通過(guò) useLocation().state 獲?。?。

<NavLink> :專為導(dǎo)航欄設(shè)計(jì),新增激活狀態(tài)相關(guān)配置,適合導(dǎo)航欄場(chǎng)景:

  • isActive:可根據(jù)激活狀態(tài)動(dòng)態(tài)設(shè)置樣式類名。
  • end:精準(zhǔn)匹配模式,防止 / 匹配到所有子路由(如 /home 不匹配 /home/detail)。

2. 編程式導(dǎo)航:useNavigate

適用于點(diǎn)擊按鈕后的邏輯處理或異步請(qǐng)求后的跳轉(zhuǎn),通過(guò) useNavigate Hook 獲取導(dǎo)航函數(shù),實(shí)現(xiàn)非點(diǎn)擊觸發(fā)的跳轉(zhuǎn)(如接口請(qǐng)求后、條件判斷后)。

const navigate = useNavigate();

// 基礎(chǔ)跳轉(zhuǎn),帶狀態(tài)
navigate('/profile', { replace: true, state: { from: 'home' } });

// 歷史記錄操作
navigate(-1); // 后退一步

三、 路由守衛(wèi):在 React 中如何“攔截”?

Vue 有原生的 beforeEach/afterEach 路由守衛(wèi),但 React Router 無(wú)專屬 API,核心通過(guò)監(jiān)聽(tīng)路由 + 條件判斷實(shí)現(xiàn),分為 3 類場(chǎng)景:

1. 全局路由守衛(wèi)

實(shí)現(xiàn)邏輯

在路由根組件(如 App.jsx)中監(jiān)聽(tīng) location 變化,執(zhí)行全局校驗(yàn)(如登錄狀態(tài)、白名單),攔截非法跳轉(zhuǎn)。

實(shí)戰(zhàn)代碼

import { useLocation, useNavigate, useEffect } from 'react-router-dom';
import { isLogin } from '@/utils/auth'; // 自定義登錄校驗(yàn)函數(shù)

// 全局路由守衛(wèi)組件
const GlobalRouterGuard = () => {
  const location = useLocation();
  const navigate = useNavigate();
  // 無(wú)需登錄的白名單路由
  const whiteList = ['/login', '/register'];

  useEffect(() => {
    // 未登錄且不在白名單 → 跳轉(zhuǎn)到登錄頁(yè)
    if (!isLogin() && !whiteList.includes(location.pathname)) {
      navigate('/login', { 
        replace: true,
        state: { from: location.pathname } // 記錄來(lái)源路徑,登錄后跳轉(zhuǎn)回去
      });
    }
  }, [location.pathname, navigate]);

  return null; // 守衛(wèi)組件無(wú)需渲染 DOM
};

// 在根路由中引入
// <BrowserRouter>
//   <GlobalRouterGuard />
//   <Routes>...</Routes>
// </BrowserRouter>

2. 組件內(nèi)路由守衛(wèi)

實(shí)現(xiàn)邏輯

在組件內(nèi)通過(guò) useEffect 實(shí)現(xiàn)進(jìn)入守衛(wèi)(組件掛載時(shí)校驗(yàn)),通過(guò) useEffect 的返回函數(shù)實(shí)現(xiàn)離開(kāi)守衛(wèi)(組件卸載時(shí)執(zhí)行)。

實(shí)戰(zhàn)代碼

import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { hasPermission } from '@/utils/permission'; // 自定義權(quán)限校驗(yàn)

const UserDetail = () => {
  const navigate = useNavigate();

  // 進(jìn)入守衛(wèi):組件掛載時(shí)校驗(yàn)權(quán)限
  useEffect(() => {
    if (!hasPermission('user:view')) {
      navigate('/403', { replace: true });
    }
  }, [navigate]);

  // 離開(kāi)守衛(wèi):組件卸載時(shí)執(zhí)行(如保存表單、提示未提交內(nèi)容)
  useEffect(() => {
    return () => {
      console.log('離開(kāi)用戶詳情頁(yè),執(zhí)行清理邏輯');
      // 業(yè)務(wù)邏輯:保存草稿、關(guān)閉WebSocket等
    };
  }, []);

  return <div>用戶詳情頁(yè)</div>;
};

3. 路由獨(dú)享守衛(wèi)

  • 概念: 不影響全局其他路由,只針對(duì)這一個(gè)頁(yè)面(或這一組頁(yè)面)進(jìn)行特殊的準(zhǔn)入檢查。 例如整個(gè)應(yīng)用都可以訪問(wèn),但只有/admin頁(yè)面需要檢查管理員權(quán)限
  • 實(shí)現(xiàn)”先創(chuàng)建一個(gè)守衛(wèi)組件AdminGuard,這個(gè)組件專門(mén)負(fù)責(zé)檢查當(dāng)前用戶是不是管理員,然后將需要單獨(dú)檢查的Admin路由套在這個(gè)守衛(wèi)組件AdminGuard里面

實(shí)戰(zhàn)代碼:

// 守衛(wèi)組件:AdminGuard.jsx
import { useNavigate } from 'react-router-dom';
import { isAdmin } from '@/utils/auth';

const AdminGuard = ({ children }) => {
  const navigate = useNavigate();
  
  // 管理員權(quán)限校驗(yàn)
  if (!isAdmin()) {
    navigate('/403', { replace: true });
    return null;
  }

  // 權(quán)限通過(guò),渲染子組件
  return children;
};

// 路由配置中使用
import { Routes, Route } from 'react-router-dom';
import SettingsPage from '@/pages/Settings';

const RouterConfig = () => {
  return (
    <Routes>
      {/* 獨(dú)享守衛(wèi):僅 /settings 路由觸發(fā)管理員校驗(yàn) */}
      <Route 
        path="/settings" 
        element={
          <AdminGuard>
            <SettingsPage />
          </AdminGuard>
        } 
      />
    </Routes>
  );
};

4.擴(kuò)展:離開(kāi)時(shí)的路由攔截(useBlocker)

useBlocker 是 React Router v6 新增 Hook,用于攔截所有路由跳轉(zhuǎn)行為(包括 <Link>、navigate、瀏覽器前進(jìn) / 后退)。

import { useBlocker } from 'react-router-dom';

// blockerFn:返回 true 攔截跳轉(zhuǎn),false 放行
// when:是否啟用攔截(可選,默認(rèn) true)
useBlocker((tx) => {
  console.log('即將跳轉(zhuǎn)到:', tx.location.pathname);
  return true; // 攔截跳轉(zhuǎn)
}, when);

實(shí)戰(zhàn)場(chǎng)景:表單未提交攔截

import { useBlocker } from 'react-router-dom';

const FormPage = () => {
  const [formDirty, setFormDirty] = useState(false); // 表單是否修改

  // 表單未提交時(shí)攔截跳轉(zhuǎn)
  useBlocker((tx) => {
    if (formDirty) {
      const confirm = window.confirm('表單內(nèi)容未保存,是否確認(rèn)離開(kāi)?');
      return !confirm; // 點(diǎn)擊取消 → 攔截(返回 true)
    }
    return false; // 放行
  }, formDirty); // 僅表單修改時(shí)啟用攔截

  return (
    <form onChange={() => setFormDirty(true)}>
      <input type="text" placeholder="輸入內(nèi)容..." />
    </form>
  );
};

四、 總結(jié)與最佳實(shí)踐

  1. 優(yōu)先使用原生 Link:對(duì)于簡(jiǎn)單的跳轉(zhuǎn),<Link> 的性能和 SEO 優(yōu)于 useNavigate。
  2. 善用 State 傳參:如果不想 URL 變得太長(zhǎng),利用 location.state 傳遞對(duì)象是最佳選擇。
  3. 守衛(wèi)邏輯模塊化:不要在 App.js 里寫(xiě)一堆 if-else,將權(quán)限校驗(yàn)封裝成獨(dú)立的 Guard 組件。

以上就是React路由監(jiān)聽(tīng)/跳轉(zhuǎn)/守衛(wèi)的完整指南的詳細(xì)內(nèi)容,更多關(guān)于React路由監(jiān)聽(tīng)/跳轉(zhuǎn)/守衛(wèi)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React拖拽調(diào)整大小的組件

    React拖拽調(diào)整大小的組件

    這篇文章主要為大家詳細(xì)介紹了React拖拽調(diào)整大小的組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 詳解在create-react-app使用less與antd按需加載

    詳解在create-react-app使用less與antd按需加載

    這篇文章主要介紹了詳解在create-react-app使用less與antd按需加載,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • 詳解React 服務(wù)端渲染方案完美的解決方案

    詳解React 服務(wù)端渲染方案完美的解決方案

    這篇文章主要介紹了詳解React 服務(wù)端渲染方案完美的解決方案,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • 如何在React中通過(guò)URL預(yù)覽Excel文件

    如何在React中通過(guò)URL預(yù)覽Excel文件

    這篇文章主要為大家詳細(xì)介紹了如何在React中通過(guò)URL預(yù)覽Excel文件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-03-03
  • React在組件中如何監(jiān)聽(tīng)redux中state狀態(tài)的改變

    React在組件中如何監(jiān)聽(tīng)redux中state狀態(tài)的改變

    這篇文章主要介紹了React在組件中如何監(jiān)聽(tīng)redux中state狀態(tài)的改變,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • React 三大屬性之state的使用詳解

    React 三大屬性之state的使用詳解

    這篇文章主要介紹了React 三大屬性之state的使用詳解,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下
    2021-04-04
  • 詳解如何使用React Hooks請(qǐng)求數(shù)據(jù)并渲染

    詳解如何使用React Hooks請(qǐng)求數(shù)據(jù)并渲染

    這篇文章主要介紹了如何使用React Hooks請(qǐng)求數(shù)據(jù)并渲染,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • React組件化條件渲染的實(shí)現(xiàn)

    React組件化條件渲染的實(shí)現(xiàn)

    本文主要介紹了React組件化條件渲染的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • react native之ScrollView下拉刷新效果

    react native之ScrollView下拉刷新效果

    這篇文章主要為大家詳細(xì)介紹了react native之ScrollView下拉刷新效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • React.InputHTMLAttributes實(shí)踐和注意事項(xiàng)

    React.InputHTMLAttributes實(shí)踐和注意事項(xiàng)

    文章討論了如何在封裝組件中使用React.InputHTMLAttributes,以及如何通過(guò) {...inputProps} 動(dòng)態(tài)傳遞屬性,最后,文章總結(jié)了使用React.InputHTMLAttributes的最佳實(shí)踐和注意事項(xiàng),感興趣的朋友一起看看吧
    2024-11-11

最新評(píng)論

万年县| 永年县| 邢台市| 江口县| 汉寿县| 新乡县| 舟曲县| 台湾省| 平湖市| 那坡县| 万山特区| 博客| 名山县| 太仓市| 江油市| 锡林浩特市| 济宁市| 石柱| 扶沟县| 滕州市| 邯郸县| 湘阴县| 静安区| 西华县| 海门市| 齐河县| 荔波县| 峨眉山市| 大同县| 连江县| 灵武市| 台北县| 弥渡县| 玉田县| 伊吾县| 千阳县| 拜泉县| 新野县| 沁阳市| 桃园县| 师宗县|