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

React中useCallback 的基本使用和原理小結(jié)

 更新時(shí)間:2025年11月05日 08:31:01   作者:老李說(shuō)技術(shù)  
React的useCallback Hook用于緩存函數(shù)定義,避免組件重渲染時(shí)重復(fù)創(chuàng)建函數(shù)實(shí)例,本文就來(lái)介紹一下React 中 useCallback 的基本使用和原理,感興趣的可以了解一下

useCallback 是 React 的一個(gè)核心 Hook,用于?緩存函數(shù)定義?,避免組件重新渲染時(shí)重復(fù)創(chuàng)建函數(shù)實(shí)例。以下是其基本使用方法:

1. 基本語(yǔ)法

const memoizedCallback = useCallback(
  () => {
    // 函數(shù)邏輯 (例如更新?tīng)顟B(tài)、調(diào)用API等)
    doSomething(a, b);
  },
  [a, b] // 依賴項(xiàng)數(shù)組
);
  • ?第一個(gè)參數(shù)?:需要緩存的函數(shù)。
  • ?第二個(gè)參數(shù)?:依賴項(xiàng)數(shù)組(Dependency Array),當(dāng)數(shù)組中的變量變化時(shí),函數(shù)會(huì)重新創(chuàng)建。

2. 核心作用

  • ?避免不必要的函數(shù)重建?:默認(rèn)情況下,組件每次渲染都會(huì)創(chuàng)建新的函數(shù)實(shí)例,使用 useCallback 后可復(fù)用函數(shù)。
  • ?優(yōu)化子組件渲染?:當(dāng)緩存的函數(shù)作為 props 傳遞給子組件(配合 React.memo)時(shí),可避免子組件不必要的重渲染?。

3. 使用示例

import React, { useState, useCallback } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  // 緩存函數(shù):依賴項(xiàng)為空數(shù)組,函數(shù)只創(chuàng)建一次
  const increment = useCallback(() => {
    setCount(prev => prev + 1); // 使用函數(shù)式更新避免閉包問(wèn)題
  }, []);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>+1</button>
    </div>
  );
}
  • 依賴項(xiàng) [] 表示函數(shù)僅在組件初次渲染時(shí)創(chuàng)建。
  • 使用 setCount(prev => prev + 1) 替代 setCount(count + 1) 可避免閉包陷阱(函數(shù)捕獲過(guò)時(shí)狀態(tài))?。

4. 適用場(chǎng)景

useCallback,本質(zhì)上是用于緩存函數(shù)。

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

但是每一次,使用useCallback,我們考慮的首要問(wèn)題是,這樣真的優(yōu)化了組件的性能嗎?其實(shí)大多數(shù)場(chǎng)景,如果不是類似列表渲染的場(chǎng)景,這樣不一定會(huì)優(yōu)化了性能。

也就是,函數(shù)作為props傳遞給性能敏感的子組件的場(chǎng)景,才是使用useCallback的時(shí)候。

useCallback的原理解析

  • useCallback 的主要目的是在依賴項(xiàng)不變的情況下,返回同一個(gè)函數(shù)引用,避免函數(shù)重復(fù)創(chuàng)建,從而優(yōu)化性能。
  • useCallback它會(huì)在首次渲染時(shí)(或依賴項(xiàng)變化時(shí))創(chuàng)建一個(gè)新的函數(shù),并將其緩存起來(lái)。在后續(xù)渲染中,如果依賴項(xiàng)沒(méi)有變化,則返回緩存的函數(shù);否則,就重新創(chuàng)建函數(shù)并更新緩存。
  • 簡(jiǎn)易的偽代碼,可能如下所示
let lastDeps; // 上一次的依賴項(xiàng)
let lastCallback; // 上一次緩存的函數(shù)

function useCallback(callback, deps) {
  if (lastDeps === undefined) {
    // 第一次調(diào)用
    lastDeps = deps;
    lastCallback = callback;
    return callback;
  }

  // 檢查依賴項(xiàng)是否變化
  const hasChanged = deps.some((dep, index) => dep !== lastDeps[index]);
  if (hasChanged) {
    lastDeps = deps;
    lastCallback = callback;
  }
  return lastCallback;
}

每次掉用useCallback,返回的函數(shù),取決于依賴項(xiàng)有沒(méi)有發(fā)生變化。

React內(nèi)部是咋樣的呢?

1、Fiber 節(jié)點(diǎn)存儲(chǔ)機(jī)制

React 在 Fiber 節(jié)點(diǎn)(組件實(shí)例對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu))中維護(hù)一個(gè) memorizedState 鏈表,專門存儲(chǔ) Hooks 狀態(tài)。

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

2、依賴項(xiàng)對(duì)比算法

源碼中的 areHookInputsEqual 對(duì)依賴數(shù)組進(jìn)行淺比較(類似 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;
}

這種優(yōu)化避免了深度比較的性能損耗

到此這篇關(guān)于React中useCallback 的基本使用和原理小結(jié)的文章就介紹到這了,更多相關(guān)React useCallback使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React?性能優(yōu)化方法總結(jié)

    React?性能優(yōu)化方法總結(jié)

    這篇文章主要介紹了React性能優(yōu)化方法總結(jié),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • react+antd動(dòng)態(tài)增刪表單方式

    react+antd動(dòng)態(tài)增刪表單方式

    這篇文章主要介紹了react+antd動(dòng)態(tài)增刪表單方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • react native仿微信PopupWindow效果的實(shí)例代碼

    react native仿微信PopupWindow效果的實(shí)例代碼

    本篇文章主要介紹了react native仿微信PopupWindow效果的實(shí)例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-08-08
  • React路由攔截模式及withRouter示例詳解

    React路由攔截模式及withRouter示例詳解

    這篇文章主要為大家介紹了React路由攔截模式及withRouter示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • React實(shí)現(xiàn)評(píng)論的添加和刪除

    React實(shí)現(xiàn)評(píng)論的添加和刪除

    這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)評(píng)論的添加和刪除,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • useCallback和useMemo的正確用法詳解

    useCallback和useMemo的正確用法詳解

    這篇文章主要為大家介紹了useCallback和useMemo的正確用法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • React SSR服務(wù)端渲染的實(shí)現(xiàn)示例

    React SSR服務(wù)端渲染的實(shí)現(xiàn)示例

    本文主要介紹了實(shí)現(xiàn)React服務(wù)端渲染,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-01-01
  • ahooks解決用戶多次提交方法示例

    ahooks解決用戶多次提交方法示例

    這篇文章主要為大家介紹了ahooks解決用戶多次提交的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • React配置代理服務(wù)器的5種方法及使用場(chǎng)景

    React配置代理服務(wù)器的5種方法及使用場(chǎng)景

    這篇文章主要介紹了React配置代理服務(wù)器的5種方法,無(wú)論使用哪種方法,都需要確保代理服務(wù)器的地址和端口正確,并且在配置完成后重新啟動(dòng)React開(kāi)發(fā)服務(wù)器,使配置生效,需要的朋友可以參考下
    2023-08-08
  • Electron+React應(yīng)用打包全流程

    Electron+React應(yīng)用打包全流程

    本文主要介紹了Electron+React應(yīng)用打包全流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01

最新評(píng)論

梓潼县| 霸州市| 正蓝旗| 依安县| 东阿县| 平定县| 和林格尔县| 蒙阴县| 翁源县| 陆丰市| 华宁县| 镇安县| 深水埗区| 永定县| 中方县| 邹城市| 成安县| 阳高县| 昌宁县| 聂拉木县| 吉木乃县| 晋中市| 锦屏县| 阳朔县| 福州市| 库伦旗| 西昌市| 汕头市| 垣曲县| 衡东县| 乌恰县| 孟津县| 定陶县| 三都| 六盘水市| 炉霍县| 当阳市| 安新县| 东山县| 石景山区| 泽库县|