React?正確使用useCallback?useMemo的方式
正確使用useCallback useMemo的姿勢
說起useCallback useMemo大家肯定在React都不陌生,但是真正了解它們的作用,還是有一部分同學(xué)對此是一知半解,只是知道用它,卻不知道它真正的含義。
今天帶大家學(xué)習(xí)一下它們的真正蘊(yùn)藏的作用。
useCallback useMemo 都是記憶函數(shù),什么是記憶函數(shù)呢?
用個最簡單的例子來講 useState 也是記憶函數(shù) 細(xì)想一下以下代碼,為什么setcount每次改變會引起組件重新render,但是count為什么不會再次被初始值0進(jìn)行賦值呢?
如果是這樣的話,我們就不能修改成功了,所以說存在某個地方保存了state的值,而這個地方是不會受到render的影響的,state就被緩存起來了。
const [count, setcount] = useState(0);
那么 useCallback useMemo 也是被緩存起來了嗎?讓我們逐個來看看
useCallback
useCallback 的作用是啥?我們來看看下面的代碼:
import React, { memo, useCallback, useState } from "react"; const HookTest = memo(() => { const [count, setcount] = useState(0); const [num, setnum] = useState(100); const showCount = () => { console.log("沒事執(zhí)行玩玩", count + "$"); }; return ( <div> <h2>HookTest:useCallback----useMemo</h2> <h3>useCallBack</h3> <h4> count:{count}---num:{num} </h4> <button onClick={showCount}>showCount</button> <button onClick={(e) => setcount(count + 3)}>+3</button> <button onClick={(e) => setnum(num * 10)}>*10</button> ); }); export default HookTest;
正常執(zhí)行的話,修改count 和 num 都會觸發(fā) render ,這是毫無疑問的。那么showCount 每次render也會被重新創(chuàng)建一次,這也是情理之中的。 但是我們想想,真的有必要每次render都重新創(chuàng)建showCount 嗎?現(xiàn)在可能只有一個函數(shù),函數(shù)體也簡單,重新創(chuàng)建也影響不了什么,但是真正開發(fā)的時候卻是我們要考慮的問題。 所以 useCallback 來幫我們解決這個問題了!
const showCount = () => { console.log("沒事執(zhí)行玩玩", count + "$"); }; const showCount = useCallback(() => { console.log("沒事執(zhí)行玩玩", count + "$"); }, [count]);
useCallback 接收兩個參數(shù) 第一個為需要緩存的函數(shù) 第二個為數(shù)組,裝載依賴
那么現(xiàn)在的 showCount 和之前的又有什么不一樣呢?
現(xiàn)在的 showCount 是被緩存起來了,組件render時,如果裝載依賴的數(shù)組中的依賴未更新,那么依然采用緩存的函數(shù)。也就是說只有當(dāng)我點(diǎn)修改count時觸發(fā)更新組件render后,showCount 也重新創(chuàng)建,但是當(dāng)我進(jìn)行其他的操作引起組件render時,由于此時條件依賴跟裝載依賴的數(shù)組中依賴毫無關(guān)系,showCount 用的是緩存里的函數(shù)。這就是 useCallback 的正確使用方法啦~
useMemo
看下面案例:
import React, { memo, useMemo, useState } from "react"; const HookTest = memo(() => { const [count, setcount] = useState(0); const [arr, setarr] = useState([ { flag: true, num: 20, }, { flag: false, num: 10, }, { flag: true, num: 40, }, { flag: true, num: 60, }, { flag: true, num: 70, }, { flag: true, num: 80, }, ]); const allNum = () => arr.reduce( (preValue, currentValue) => currentValue.flag ? preValue + currentValue.num : preValue, 0 ); return ( <div> <h2>HookTest:useCallback----useMemo</h2> <h3>useMemo</h3> <h4> count:{count} </h4> <button onClick={(e) => setcount(count + 3)}>+3</button> <h4>all:{allNum}</h4> </div> ); }); export default HookTest;
很簡單的小案例,根據(jù)條件對數(shù)組求和操作,同樣我們點(diǎn)擊修改count 然后組件重新render
此時我們考慮一個問題,是不是 allNum 又進(jìn)行了一次復(fù)雜的運(yùn)行然后得到結(jié)果?現(xiàn)在看來才幾條數(shù)據(jù),怎么復(fù)雜了,我們得考慮數(shù)組若是幾百上千上萬呢?我們都知道組件渲染是很頻繁的,那么每次渲染我們真的有必要去每次進(jìn)行復(fù)雜的運(yùn)算嗎?
所以這就是性能優(yōu)化的另一個點(diǎn)了 引出 useMemo來幫助我們解決
將allNum 改造后:
const allNum = () => arr.reduce( (preValue, currentValue) => currentValue.flag ? preValue + currentValue.num : preValue, 0 ); const allNum = useMemo( () => arr.reduce( (preValue, currentValue) => currentValue.flag ? preValue + currentValue.num : preValue, 0 ), [arr] );
useMemo 同樣接收兩個參數(shù) 第一個參數(shù)是函數(shù)的返回值!! 第二個為數(shù)組,裝載依賴
用了之后呢?有那些改變呢?
現(xiàn)在 allNum 不再是一個函數(shù)了,而是一個返回值現(xiàn)在如果進(jìn)行和依賴數(shù)組無關(guān)的render時,allNum 將采用上次緩存的返回值,不用再去傻傻的計(jì)算一遍啦。
總結(jié)
簡單給大家總結(jié)下:
- useCallback 緩存函數(shù)
- useMemo 緩存函數(shù)返回值
- 都是解決組件頻繁渲染從而頻繁創(chuàng)建函數(shù)及頻繁運(yùn)行函數(shù)
- 正確的思路應(yīng)該是 跟我有關(guān)的時候我才需要去重新創(chuàng)建函
到此這篇關(guān)于React 正確使用useCallback useMemo的方式的文章就介紹到這了,更多相關(guān)React useCallback useMemo內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react?card?slider實(shí)現(xiàn)滑動卡片教程示例
這篇文章主要為大家介紹了react?card?slider實(shí)現(xiàn)滑動卡片教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09React?Native性能優(yōu)化指南及問題小結(jié)
本文將介紹在React?Native開發(fā)中常見的性能優(yōu)化問題和解決方案,包括ScrollView內(nèi)無法滑動、熱更新導(dǎo)致的文件引用問題、高度獲取、強(qiáng)制橫屏UI適配、低版本RN適配iOS14、緩存清理、navigation參數(shù)取值等,感興趣的朋友一起看看吧2024-01-01React組件實(shí)例三大屬性state props refs使用詳解
這篇文章主要為大家介紹了React組件實(shí)例三大屬性state props refs使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09react-native使用react-navigation進(jìn)行頁面跳轉(zhuǎn)導(dǎo)航的示例
本篇文章主要介紹了react-native使用react-navigation進(jìn)行頁面跳轉(zhuǎn)導(dǎo)航的示例,具有一定的參考價值,有興趣的可以了解一下2017-09-09