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

一文帶你搞懂useCallback的使用方法

 更新時間:2023年02月07日 11:56:41   作者:Kobe_G  
useCallback是用來幫忙緩存函數(shù)的,當依賴項沒有發(fā)生變化時,返回緩存的指針,而props涉及到復雜對象類型都是通過指針來傳遞到,下面這篇文章主要給大家介紹了關(guān)于useCallback使用的相關(guān)資料,需要的朋友可以參考下

一、useCallback的作用

usecallback不是用來解決組件中有過多內(nèi)部函數(shù)導致的性能問題:

1.我們要知道,js創(chuàng)建一個函數(shù)的成本是非常小的,這點計算對于計算機來說是小case

2.其實使用useCallback會產(chǎn)成額外的性能:對deps的判斷

3.其實每次組件重新渲染時,都無所謂避免重新創(chuàng)建內(nèi)部函數(shù),因為即使useCallback的deps沒有變,它也會重新創(chuàng)建內(nèi)部函數(shù)作為useCallback的實參

那么,它的作用到底是什么?useCallback的作用其實是用來避免子組件不必要的reRender:

首先,假如我們不使用useCallback,在父組件中創(chuàng)建了一個名為handleClick的事件處理函數(shù),根據(jù)需求我們需要把這個handleClick傳給子組件,當父組件中的一些state變化后(這些state跟子組件沒有關(guān)系),父組件會reRender,然后會重新創(chuàng)建名為handleClick函數(shù)實例,并傳給子組件,這時即使用React.memo把子組件包裹起來,子組件也會重新渲染,因為props已經(jīng)變化了,但這個渲染是無意義的

如何優(yōu)化呢?這時候就可以用useCallback了,我們用useCallback把函數(shù)包起來之后,在父組件中只有當deps變化的時候,才會創(chuàng)建新的handleClick實例,子組件才會跟著reRender(注意,必須要用React.memo把子組件包起來才有用,否則子組件還是會reRender。React.memo是類似于class組件中的Pure.Component的作用)

對于這種deps不是經(jīng)常變化的情況,我們用useCallback和React.memo的方式可以很好地避免子組件無效的reRender。但其實社區(qū)中對這個useCallback的使用也有爭議,比如子組件中只是渲染了幾個div,沒有其他的大量計算,而瀏覽器去重新渲染幾個dom的性能損耗其實也是非常小的,我們花了這么大的勁,使用了useCallback和React.memo,換來的收益很小,所以一些人認為就不用useCallback,就讓瀏覽器去重新渲染好了。至于到底用不用,此處不深入討論,我的建議是當子組件中的dom數(shù)量很多,或者有一些大量的計算操作,是可以進行這樣的優(yōu)化的。

以上都是討論的deps不會經(jīng)常改變的情況的優(yōu)化,而很多時候useCallback中的deps數(shù)組中的變量是會經(jīng)常改變的,這個時候我們用useCallback已經(jīng)沒啥意義了,反而會造成性能損耗(deps判斷)。有沒有什么辦法可以讓子組件不重新渲染,也能拿到父組件中handleClick函數(shù)中的最新state值呢?下面我們討論useRef,useReducer,usePersistFn這三種解決方法

二、useRef解決方案

為了讓子組件不進行reRender,我們必須保證

1.父組件不會重新創(chuàng)建handleClick函數(shù)實例

2.handleClick函數(shù)能拿到最新的state

使用useRef

const [text, setText] = useState('Initial value');
const textRef = useRef(text);
const handleClick= useCallback(() => {
     console.log(textRef.current);
 }, []); 

 useEffect(() => {
     console.log('update text')
     textRef.current = text;
 }, [text])

textRef在每次reRender時不會改變,這樣我們把handleClick傳給子組件,handleClick函數(shù)中每次都能拿到父組件中最新的state

三、useReducer解決方案

使用useReducer

function reducer(state, action) {
    switch(action.type) {
        case 'update':
            return action.preload;
        case 'childComponent':
            // 要執(zhí)行的函數(shù)  
            return state;     
    }
}
export default function Index() { // 父組件
    const [state, dispatch] = useReducer(reducer, 'Initial value');

    return (
        <>
            <input value={state} onChange={(e) => dispatch({
                type: 'update', 
                preload: e.target.value
            })} />
            <ChildComponent dispatch={dispatch} />
        </>
    )
}

//在 ChildComponent中,拿到dispatch,通過dispatch({type: 'childComponent' })的方式調(diào)用

dispatch自帶memoize,所以子組件不會進行 re-render

四、usePersistFn解決方案

usePersistFn是aooks庫中的一個鉤子函數(shù),它接收一個函數(shù),返回一個永遠不變的函數(shù)引用,在這個函數(shù)中每次都能拿到最新的state值,看看usePersistFn的源碼:

function usePersistFn(fn) {
  const fnRef = useRef(fn);
  fnRef.current = fn;

  const persistFn = useRef();
  if (!persistFn.current) {
    persistFn.current = function (...args) {
      return fnRef.current.apply(this, args);
    };
  }

  return persistFn.crrent;
}

這里它用了兩個useRef,保證返回的函數(shù)引用不變,并且每次函數(shù)內(nèi)部能拿到最新的state。

這里可以用useRef和useCallback到達同樣的效果:

function usePersistFn(fn) {
  const fnRef = useRef();
  fnRef.current = fn; 
	
  const persist= useCallback((...rest) => {
     return fnRef.current(...rest);
  }, []);
  
  return persist
}

這種方法和上面的useRef解決方案差不多,只是封裝了起來而已

另外,本文介紹一下useContext使用的問題和優(yōu)化:

問題:當context中的值改變時,只要使用useContext訂閱了context的組件,不管該組件用到的state改不改變,該組件都會reRender,此時用React.memo是沒有辦法優(yōu)化的。

優(yōu)化:

1.拆分context,把經(jīng)常改變的數(shù)據(jù)和不經(jīng)常改變的數(shù)據(jù)拆分開,在只使用穩(wěn)定數(shù)據(jù)的組件中,我們只使用stableContext

2.使用useMemo

const {state}= useContext(AppContext);
return useMemo(() => <span>data:{state.depData}</span>, [state.depData]);

3.如何有效減少使用useContext導致的不必要渲染

總結(jié)

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

相關(guān)文章

  • React?中的列表渲染要加?key的原因分析

    React?中的列表渲染要加?key的原因分析

    這篇文章主要介紹了React?中的列表渲染為什么要加?key,在?React?中我們經(jīng)常需要渲染列表,比如展示好友列表,文中給大家介紹了列表渲染不提供?key?會如何,通過實例代碼給大家介紹的非常詳細,需要的朋友一起看看吧
    2022-07-07
  • react如何獲取state的值并更新使用

    react如何獲取state的值并更新使用

    這篇文章主要介紹了react如何獲取state的值并更新使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • React的createElement和render手寫實現(xiàn)示例

    React的createElement和render手寫實現(xiàn)示例

    這篇文章主要為大家介紹了React的createElement和render手寫實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • React常見的?HOC?使用案例及示例代碼

    React常見的?HOC?使用案例及示例代碼

    高階組件(Higher-Order?Component,HOC)是一種用于在?React?中復用組件邏輯的技術(shù),這篇文章主要介紹了React常見的?HOC?使用案例示例代碼,需要的朋友可以參考下
    2024-08-08
  • React+valtio響應式狀態(tài)管理

    React+valtio響應式狀態(tài)管理

    Valtio是一個很輕量級的響應式狀態(tài)管理庫,使用外部狀態(tài)代理去驅(qū)動React視圖來更新,本文主要介紹了React+valtio響應式狀態(tài)管理,感興趣的可以了解一下
    2023-12-12
  • React中 Zustand狀態(tài)管理庫的使用詳解

    React中 Zustand狀態(tài)管理庫的使用詳解

    Zustand?是一個非常輕量、簡潔的狀態(tài)管理庫,旨在為 React 提供簡便且高效的狀態(tài)管理,相比于 Redux 或 Context API,Zustand 具有更簡潔、靈活和易于理解的優(yōu)點,感興趣的朋友一起看看吧
    2024-12-12
  • react?hooks?UI與業(yè)務邏輯分離必要性技術(shù)方案

    react?hooks?UI與業(yè)務邏輯分離必要性技術(shù)方案

    這篇文章主要為大家介紹了react?hooks?UI與業(yè)務邏輯分離必要性技術(shù)方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • 在React中實現(xiàn)txt文本文件預覽的完整指南

    在React中實現(xiàn)txt文本文件預覽的完整指南

    在前端開發(fā)中,從遠程 URL 加載并預覽文本文件是一項實用且常見的功能,今天,我將帶你深入剖析一個 React 組件 TextViewerURL,它通過 URL 加載文本文件,支持多種編碼),并搭配精心設(shè)計的樣式,讓文本展示更美觀、交互更友好,感興趣的小伙伴跟著小編一起來看看吧
    2025-03-03
  • React中Portal的具體使用

    React中Portal的具體使用

    React中的Portal允許開發(fā)者將組件渲染到DOM樹的不同位置,本文主要介紹了React中Portal的具體使用,具有一定的參考價值,感興趣的可以了解一下
    2025-02-02
  • 詳解如何使用React?Redux實現(xiàn)異步請求

    詳解如何使用React?Redux實現(xiàn)異步請求

    這篇文章主要為大家詳細介紹了如何使用React?Redux實現(xiàn)異步請求,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考一下
    2025-01-01

最新評論

岑溪市| 娱乐| 调兵山市| 屯留县| 黎川县| 鄢陵县| 乌兰浩特市| 玉田县| 罗甸县| 静海县| 云霄县| 宣威市| 宣汉县| 沾益县| 桂东县| 秦安县| 南通市| 武陟县| 徐州市| 滦南县| 海原县| 安阳县| 温宿县| 赫章县| 广丰县| 北辰区| 青川县| 沅江市| 确山县| 得荣县| 福泉市| 昌江| 卢湾区| 西乡县| 康乐县| 田阳县| 三穗县| 桦南县| 吉水县| 泰州市| 乌鲁木齐县|