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

React手把手帶你實現(xiàn)Keep-Alive效果的三種方法

 更新時間:2026年03月22日 15:19:24   作者:發(fā)現(xiàn)一只大呆瓜  
在Vue中,我們可以通過<keep-alive>輕松緩存組件實例,但在React中,組件卸載意味著狀態(tài)和DOM的徹底銷毀,下面就來詳細的介紹三種實現(xiàn)方法,感興趣的可以了解一下

前言

在 Vue 中,我們可以通過 <keep-alive> 輕松緩存組件實例。但在 React 中,組件卸載(Unmount)意味著狀態(tài)和 DOM 的徹底銷毀。如何在 React 中實現(xiàn)“切換頁面不丟失滾動位置、不重置表單”?本文將為你拆解三種主流方案。

一、 Keep-Alive 的本質(zhì)是什么?

在實現(xiàn) React 版緩存組件前,先明確 Vue keep-alive 的核心邏輯,才能精準復刻:

  • 核心本質(zhì):緩存組件實例,保留組件內(nèi)部狀態(tài)(如輸入框內(nèi)容、滾動位置);
  • 行為特征:組件切換時不銷毀 / 重建,僅通過「隱藏 / 顯示」控制渲染狀態(tài);
  • React 目標:實現(xiàn)和 Vue 一致的效果 —— 組件切走不丟狀態(tài),切回來能恢復。

二、 React 實現(xiàn) keep-alive 的 3 種方案

方案 1:CSS 隱藏 + 不卸載組件(最簡單)

核心思路:

通過 display: none 隱藏不活躍的組件,保留組件的 DOM 節(jié)點和內(nèi)部狀態(tài),僅切換 display 屬性控制顯示 / 隱藏,不觸發(fā)組件的卸載 / 重新掛載生命周期。

適用場景

  • 少量組件切換(2-3 個,如 tab 標簽頁);
  • 簡單業(yè)務場景(如表單頁、列表頁切換)。

優(yōu)缺點

? 優(yōu)點:實現(xiàn)簡單,無額外依賴,狀態(tài)保留完整;

? 缺點:所有組件都會掛載在 DOM 樹中,組件數(shù)量多(如 5 個以上)會增加 DOM 節(jié)點數(shù)量,可能影響頁面渲染性能。

import { useState } from 'react';
// 模擬 Tab 切換場景
const KeepAliveByCSS = () => {
  // 控制當前激活的標簽
  const [activeKey, setActiveKey] = useState('tab1');
  return (
    <div>
      <div className="tab-header">
        <button onClick={() => setActiveKey('tab1')}>標簽1</button>
        <button onClick={() => setActiveKey('tab2')}>標簽2</button>
      </div>
      <div className="tab-content">
        {/* 始終掛載,僅通過 CSS 隱藏 */}
        <div style={{ display: activeKey === 'tab1' ? 'block' : 'none' }}>
          <Tab1 />
        </div>
        <div style={{ display: activeKey === 'tab2' ? 'block' : 'none' }}>
          <Tab2 />
        </div>
      </div>
    </div>
  );
};
// 帶狀態(tài)的子組件
const Tab1 = () => {
  // 切換標簽后,輸入框內(nèi)容不會丟失
  const [inputVal, setInputVal] = useState('');
  return <input value={inputVal} onChange={(e) => setInputVal(e.target.value)} placeholder="標簽1輸入框" />;
};
const Tab2 = () => {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>計數(shù):{count}</p>
      <button onClick={() => setCount(count + 1)}>增加</button>
    </div>
  );
};

方案 2:使用react-activation第三方庫(推薦)

這是目前社區(qū)內(nèi)最成熟的方案,它通過將組件渲染到“外部容器”再動態(tài)掛載回來的方式,模擬了 Vue 的行為。

核心功能

  • 提供 <KeepAlive> 容器組件,包裹需要緩存的組件即可生效;
  • 內(nèi)置 useActivate/useDeactivate 鉤子函數(shù),分別在組件「激活」和「失活」時觸發(fā);
  • 支持緩存控制(如指定緩存 Key、條件緩存);
  • 能保留 DOM 狀態(tài)(如滾動條位置、輸入框焦點)。

使用示例

import { KeepAlive, useActivate, useDeactivate } from 'react-activation';
import { useState } from 'react';
const KeepAliveByLib = () => {
  const [show, setShow] = useState(true);
  return (
    <div>
      <button onClick={() => setShow(!show)}>
        {show ? '隱藏組件' : '顯示組件'}
      </button>
      {/* 用 KeepAlive 包裹需要緩存的組件 */}
      {show && (
        <KeepAlive id="cached-component">
          <CachedComponent />
        </KeepAlive>
      )}
    </div>
  );
};
// 被緩存的組件
const CachedComponent = () => {
  const [inputVal, setInputVal] = useState('');
  const [scrollTop, setScrollTop] = useState(0);
  // 組件激活時觸發(fā)(顯示時)
  useActivate(() => {
    console.log('組件被激活');
  });
  // 組件失活時觸發(fā)(隱藏時)
  useDeactivate(() => {
    console.log('組件被失活');
  });
  // 模擬滾動條狀態(tài)保留
  const handleScroll = (e) => {
    setScrollTop(e.target.scrollTop);
  };
  return (
    <div>
      <input 
        value={inputVal} 
        onChange={(e) => setInputVal(e.target.value)} 
        placeholder="緩存的輸入框" 
      />
      <div 
        style={{ height: '200px', overflow: 'auto', marginTop: '10px' }}
        onScroll={handleScroll}
      >
        {Array.from({ length: 50 }).map((_, index) => (
          <p key={index}>滾動測試行 {index + 1}</p>
        ))}
      </div>
      <p>當前滾動位置:{scrollTop}</p>
    </div>
  );
};

方案 3:全局狀態(tài)管理 + 狀態(tài)回顯(Redux)

如果不想引入第三方庫,也可以通過全局狀態(tài)緩存實現(xiàn)核心效果,本質(zhì)是組件卸載前存狀態(tài),重新掛載時取狀態(tài)。

核心思路

在組件 useEffect 的清理函數(shù)中,將關(guān)鍵數(shù)據(jù)(輸入框、計數(shù)、滾動位置等)保存到全局 Store;重新掛載時再讀取初始化。

  • 優(yōu)點:符合 React 數(shù)據(jù)流規(guī)范,內(nèi)存占用可控。

  • 缺點

    1. 無法恢復 DOM 狀態(tài):如頁面的滾動位置、輸入框的焦點、已播放的視頻進度,需單獨編寫邏輯處理。
    2. 開發(fā)成本高:每個需要緩存的組件都要手動編寫保存/恢復邏輯。
  • 補救措施:若要恢復滾動位置,需手動在卸載前記錄 scrollTop,并在渲染后通過 window.scrollTo 還原。

三、緩存 React Router 路由組件

實際開發(fā)中,最常見的場景是切換路由不丟失頁面狀態(tài)(如列表頁滾動位置、表單輸入內(nèi)容),可結(jié)合 React Router + react-activation 實現(xiàn)。

核心代碼如下:

import { BrowserRouter, Routes, Route, useLocation } from 'react-router-dom';
import { KeepAlive } from 'react-activation';
import Profile from './pages/Profile';
import Home from './pages/Home';
import Settings from './pages/Settings';
// 路由容器組件(獲取當前路由路徑)
const RouterContainer = () => {
  const location = useLocation();
  const currentPath = location.pathname;
  return (
    <Routes>
      {/* 普通路由(不緩存) */}
      <Route path="/" element={<Home />} />
      <Route path="/settings" element={<Settings />} />
      {/* 緩存路由組件:when 控制是否緩存,id 為緩存標識 */}
      <Route
        path="/profile"
        element={
          <KeepAlive id="profile" when={currentPath === "/profile"}>
            <Profile />
          </KeepAlive>
        }
      />
    </Routes>
  );
};
// 根組件
const App = () => {
  return (
    <BrowserRouter>
      <RouterContainer />
    </BrowserRouter>
  );
};

四、 方案選擇建議

方案優(yōu)點缺點適用場景
CSS 隱藏實現(xiàn)簡單、無依賴DOM 節(jié)點冗余、性能一般少量組件(2-3 個)、簡單 tab 切換
react-activation功能完整、支持 DOM 狀態(tài)緩存新增第三方依賴中大型項目、需完整 keep-alive 效果
全局狀態(tài)緩存無額外依賴、貼合狀態(tài)管理僅恢復數(shù)據(jù)、需手動處理 DOM已用全局狀態(tài)庫、僅需數(shù)據(jù)緩存

五、總結(jié)

  1. React 無原生 keep-alive,但可通過CSS 隱藏、react-activation 庫、全局狀態(tài)緩存3 種方案模擬核心效果;
  2. 簡單場景用 CSS 隱藏,中大型項目優(yōu)先選 react-activation(兼顧易用性和完整性);
  3. 路由組件緩存可結(jié)合 React Router + react-activation 實現(xiàn),核心是通過 KeepAlive 包裹路由元素并指定緩存標識。

到此這篇關(guān)于React手把手帶你實現(xiàn)Keep-Alive效果的三種方法的文章就介紹到這了,更多相關(guān)React實現(xiàn)Keep-Alive內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React Ref Callback使用場景最佳實踐詳解

    React Ref Callback使用場景最佳實踐詳解

    這篇文章主要為大家介紹了React Ref Callback使用場景最佳實踐詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • 在React框架中實現(xiàn)一些AngularJS中ng指令的例子

    在React框架中實現(xiàn)一些AngularJS中ng指令的例子

    這篇文章主要介紹了在JavaScript的React框架中實現(xiàn)一些AngularJS指令的例子,React使用Virtual DOM因而與普通的js框架有些不同,需要的朋友可以參考下
    2016-03-03
  • 解決react組件渲染兩次的問題

    解決react組件渲染兩次的問題

    這篇文章主要介紹了解決react組件渲染兩次的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • create-react-app項目配置全解析

    create-react-app項目配置全解析

    這篇文章主要為大家介紹了create-react-app項目配置全解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • React點擊事件的兩種寫法小結(jié)

    React點擊事件的兩種寫法小結(jié)

    這篇文章主要介紹了React點擊事件的兩種寫法小結(jié),具有很好的參考價值,希望對大家有所幫助。
    2022-12-12
  • React Native使用百度Echarts顯示圖表的示例代碼

    React Native使用百度Echarts顯示圖表的示例代碼

    本篇文章主要介紹了React Native使用百度Echarts顯示圖表的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • React初始化渲染過程示例詳解

    React初始化渲染過程示例詳解

    這篇文章主要為大家介紹了React初始化渲染過程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • React?Native實現(xiàn)Toast輕提示和loading效果

    React?Native實現(xiàn)Toast輕提示和loading效果

    這篇文章主要介紹了React Native實現(xiàn)Toast輕提示和loading效果,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • React Hooks之useRef獲取元素示例詳解

    React Hooks之useRef獲取元素示例詳解

    這篇文章主要介紹了React Hooks之useRef獲取元素示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • react 組件傳值的三種方法

    react 組件傳值的三種方法

    這篇文章主要介紹了react 組件傳值的三種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-06-06

最新評論

闽侯县| 玛多县| 东阿县| 彭山县| 广东省| 师宗县| 班戈县| 尚义县| 松潘县| 隆林| 旅游| 阜南县| 嘉禾县| 泰安市| 龙山县| 南丰县| 上林县| 同德县| 沙湾县| 横峰县| 浦北县| 霞浦县| 永康市| 枝江市| 西充县| 自治县| 盘山县| 苗栗县| 湄潭县| 罗江县| 桓仁| 吉木萨尔县| 惠东县| 溧阳市| 高密市| 浮梁县| 理塘县| 东乡县| 贵州省| 尚义县| 闸北区|