<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      React 中 useCallback 的基本使用和原理解析

      React 中 useCallback 的基本使用方法

      useCallback 是 React 的一個核心 Hook,用于?緩存函數定義?,避免組件重新渲染時重復創建函數實例。以下是其基本使用方法:

      1. 基本語法

      const memoizedCallback = useCallback(
        () => {
          // 函數邏輯 (例如更新狀態、調用API等)
          doSomething(a, b);
        },
        [a, b] // 依賴項數組
      );
      
      • ?第一個參數?:需要緩存的函數。
      • ?第二個參數?:依賴項數組(Dependency Array),當數組中的變量變化時,函數會重新創建。

      2. 核心作用

      • ?避免不必要的函數重建?:默認情況下,組件每次渲染都會創建新的函數實例,使用 useCallback 后可復用函數。
      • ?優化子組件渲染?:當緩存的函數作為 props 傳遞給子組件(配合 React.memo)時,可避免子組件不必要的重渲染?。

      3. 使用示例

      import React, { useState, useCallback } from 'react';
      
      function Counter() {
        const [count, setCount] = useState(0);
      
        // 緩存函數:依賴項為空數組,函數只創建一次
        const increment = useCallback(() => {
          setCount(prev => prev + 1); // 使用函數式更新避免閉包問題
        }, []);
      
        return (
          <div>
            <p>Count: {count}</p>
            <button onClick={increment}>+1</button>
          </div>
        );
      }
      
      • 依賴項 [] 表示函數僅在組件初次渲染時創建。
      • 使用 setCount(prev => prev + 1) 替代 setCount(count + 1) 可避免閉包陷阱(函數捕獲過時狀態)?。

      4. 適用場景

      useCallback,本質上是用于緩存函數。

      如果函數,是以props的方式,傳遞給子組件,為了每次避免子組件的渲染,建議使用useCallback進行包裹。

      但是每一次,使用useCallback,我們考慮的首要問題是,這樣真的優化了組件的性能嗎?其實大多數場景,如果不是類似列表渲染的場景,這樣不一定會優化了性能。

      也就是,函數作為props傳遞給性能敏感的子組件的場景,才是使用useCallback的時候。

      useCallback 的原理解析

      • useCallback 的主要目的是在依賴項不變的情況下,返回同一個函數引用,避免函數重復創建,從而優化性能。
      • useCallback它會在首次渲染時(或依賴項變化時)創建一個新的函數,并將其緩存起來。在后續渲染中,如果依賴項沒有變化,則返回緩存的函數;否則,就重新創建函數并更新緩存。
      • 簡易的偽代碼,可能如下所示
      let lastDeps; // 上一次的依賴項
      let lastCallback; // 上一次緩存的函數
      
      function useCallback(callback, deps) {
        if (lastDeps === undefined) {
          // 第一次調用
          lastDeps = deps;
          lastCallback = callback;
          return callback;
        }
      
        // 檢查依賴項是否變化
        const hasChanged = deps.some((dep, index) => dep !== lastDeps[index]);
        if (hasChanged) {
          lastDeps = deps;
          lastCallback = callback;
        }
        return lastCallback;
      }
      

      每次掉用useCallback,返回的函數,取決于依賴項有沒有發生變化。

      React內部是咋樣的呢?

      1、Fiber 節點存儲機制

      React 在 Fiber 節點(組件實例對應的數據結構)中維護一個 memorizedState 鏈表,專門存儲 Hooks 狀態。

      function updateCallback(callback, deps) {
        const hook = updateWorkInProgressHook(); // 獲取當前 Hook 節點
        const nextDeps = deps === undefined ? null : deps;
        const prevState = hook.memoizedState;     // 讀取緩存的上次狀態
        
        // 依賴項對比:使用淺比較(shallow equal)
        if (prevState !== null && areHookInputsEqual(nextDeps, prevState[1])) {
          return prevState[0]; // 返回緩存的函數
        }
        
        //  依賴變化:緩存新函數
        hook.memoizedState = [callback, nextDeps];
        return callback;
      }
      

      2、依賴項對比算法

      源碼中的 areHookInputsEqual 對依賴數組進行淺比較(類似 Object.is):

      function areHookInputsEqual(nextDeps, prevDeps) {
        if (prevDeps === null) return false;
        for (let i = 0; i < prevDeps.length; i++) {
          if (!Object.is(nextDeps[i], prevDeps[i])) {
            return false;
          }
        }
        return true;
      }
      

      這種優化避免了深度比較的性能損耗

      posted @ 2025-11-04 23:20  老李說技術  閱讀(5)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久人妻精品国产| 久久久久无码精品国产h动漫| 美女人妻激情乱人伦| 包头市| 久久99日韩国产精品久久99| 精品国产中文字幕懂色| 成人看的污污超级黄网站免费| 亚洲一区成人在线视频| 激情一区二区三区成人文| 中超| 浮妇高潮喷白浆视频| 亚洲精品中文字幕无码蜜桃 | 青青草无码免费一二三区| 亚洲中国精品精华液| 免费无码一区无码东京热| 亚洲熟女乱一区二区三区| 99国产欧美另类久久久精品| 精品中文人妻中文字幕| 亚洲综合小说另类图片五月天| 亚洲精品综合网在线8050影院| 国产又黄又爽又不遮挡视频| bt天堂新版中文在线| 国产午夜精品久久久久免费视| 亚洲一区二区三区色视频| 国产中文一区卡二区不卡| 国产黄色精品一区二区三区| 国产精品久久久久aaaa| 国产欧美综合在线观看第十页| 国产熟女真实乱精品51| 国产一区在线播放av| 国产精品护士| 欧美 亚洲 中文 国产 综合| 久久99日韩国产精品久久99| 国内视频偷拍久久伊人网| 伊人激情av一区二区三区| 张北县| 亚洲国产日韩精品久久| 欧美福利电影A在线播放| 国产精品久久久久久久网| 欧洲精品一区二区三区久久 | 在线看国产精品自拍内射|