react-useMemo/useCallback/memo使用

react提供useMemo/useCallback/memo方法,提高頁面刷新效率勋乾。若組件依賴的屬性沒有發(fā)送變化,組件可以不刷新句狼。以下提供兩個場景的具體使用

單組件內(nèi)使用

使用語法

import React, { useMemo } from 'react'
useMemo(() => {}, [] ) 
  • 1.useMemo第一個參數(shù)是函數(shù)许起,第二個參數(shù)是數(shù)組
  • 2.如果第二個參數(shù)不傳遞十偶,與useEffect類似,意味著每次都會執(zhí)行第一個函數(shù)參數(shù)园细,則使用useMem就毫無意義
  • 3.如果第二個參數(shù)傳的是空數(shù)組[]惦积, 與useEffect類似,只執(zhí)行一次,類似類組件componentDidmount
  • 4.useMemouseEffect有不一樣的一點(diǎn)就是調(diào)用時機(jī) —— useEffect執(zhí)行的是副作用猛频,所以一定是在渲染之后運(yùn)行的狮崩;而useMemo是需要有返回值的,返回值會參與渲染鹿寻,所以useMemo是是在渲染期間完成的睦柴。
  • 5.useMemo,定義了一段函數(shù)邏輯毡熏,根據(jù)第二個參數(shù)判斷是否執(zhí)行第一個函數(shù)執(zhí)行

useMemo

case1 (不設(shè)置第二個參數(shù)坦敌,無優(yōu)化效果)

  • useMemo第二個參數(shù)不設(shè)置
  • 代碼表現(xiàn):每次點(diǎn)擊點(diǎn)擊+1,控制臺打印double痢法,同時標(biāo)簽Double每次刷新
  • 代碼解析:useMemo第二個參數(shù)不設(shè)置狱窘,頁面首次加載和頁面更新,都會重新加載<div>Double is :{double}</div>
import React, {useState, useCallback, useEffect, useMemo, memo} from 'react'
// 函數(shù)組件财搁,當(dāng)前組件中useMemo的使用
function App() {
    const [count, setCount] = useState(0)
    const double = useMemo(()=>{
        console.log('double')
        return count * 2
    })//關(guān)注點(diǎn)
    return (
        <div>
            <button onClick={() => {
                setCount(count + 1)
            }}>點(diǎn)擊+1
            </button>
            <div>Count is :{count}</div>
            <div>Double is :{double}</div>
        </div>
    )
}

case2 (設(shè)置第二個參數(shù)為[]蘸炸,首次加載更新)

  • useMemo第二個參數(shù)設(shè)置為[],這組件只會在頁面首次加載更新妇拯,類似類組件的componentDidMount
  • 代碼表現(xiàn):頁面首次加載幻馁,控制臺打印double;每次點(diǎn)擊點(diǎn)擊+1越锈,控制臺打印無打印日志仗嗦,同時標(biāo)簽Double始終為0
  • 代碼解析:useMemo第二個參數(shù)設(shè)置[]<div>Double is :{double}</div>只有在首次頁面加載甘凭,即double變化了稀拐,也不會改變標(biāo)簽的
import React, {useState, useCallback, useEffect, useMemo, memo} from 'react'

// 函數(shù)組件,當(dāng)前組件中useMemo的使用
function App() {
    const [count, setCount] = useState(0)

    const double = useMemo(()=>{
        console.log('double')
        return count * 2
    },[])  //關(guān)注點(diǎn)

    return (
        <div>
            <button onClick={() => {
                setCount(count + 1)
            }}>點(diǎn)擊+1
            </button>
            <div>Count is :{count}</div>
            <div>Double is :{double}</div>
        </div>
    )
}

case3 (設(shè)置第二個參數(shù)為[count===2])

  • useMemo第二個參數(shù)設(shè)置為[count===2]
  • 代碼表現(xiàn):頁面首次加載丹弱,控制臺打印double德撬;點(diǎn)擊點(diǎn)擊+1,當(dāng)count=2躲胳,count=3的時候控制臺打印double蜓洪,同時標(biāo)簽<div>Double is :{double}</div>更新兩次,分別為Double is :4Double is :6
  • 代碼解析:useMemo第二個參數(shù)設(shè)置[count===2]坯苹,表示當(dāng)count===2的時候才會更新組件隆檀,count1,2,3對應(yīng)count===2變化為false, true, false恐仑,因此只有2次刷新
import React, {useState, useCallback, useEffect, useMemo, memo} from 'react'

// 函數(shù)組件泉坐,當(dāng)前組件中useMemo的使用
function App() {
    const [count, setCount] = useState(0)

    const double = useMemo(()=>{
        console.log('double')
        return count * 2
    },[count===2])  //關(guān)注點(diǎn)

    return (
        <div>
            <button onClick={() => {
                setCount(count + 1)
            }}>點(diǎn)擊+1
            </button>
            <div>Count is :{count}</div>
            <div>Double is :{double}</div>
        </div>
    )
}

父子組件內(nèi)使用

目標(biāo):

子組件的依賴屬性更新,才會重新加載子組件

操作:

  • 1.子組件用memo聲明裳仆,
  • 2.子組件對父組件依賴的所有屬性useCallback或者useMemo聲明

子組件沒用memo聲明

程序響應(yīng):

    1. <Counter counter = {double}></Counter> 當(dāng)count為2腕让,3的時候,double發(fā)生變化
  • 2.每次count變化歧斟,子組件都會重新渲染(控制臺打印日志counter

代碼如下

function Counter(props) {
    console.log('counter')
    return (
        <div>
            double is : {props.counter}
        </div>
    )
}
function App (){
    const [count, setCount] = useState(0)

    const double = useMemo(()=>{
        return count * 2
    }, [count === 2])

    return (
        <div>
            <button onClick={()=>{setCount(count + 1)}}>點(diǎn)擊+1</button>
            <div>count is : {count}</div>
            <Counter counter = {double}></Counter>
        </div>
    )
}

子組件用memo聲明

程序響應(yīng):

    1. <Counter counter = {double}></Counter> 當(dāng)count為2纯丸,3的時候,double發(fā)生變化
  • 2.當(dāng)count為2构捡,3的時候液南,子組件會重新渲染(控制臺打印日志counter

代碼如下

const Counter = memo(function Counter(props) {
    console.log('counter')
    return (
        <div>
            double is : {props.counter}
        </div>
    )
})

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

    const double = useMemo(()=>{
        return count * 2
    }, [count === 2])

    return (
        <div>
            <button onClick={()=>{setCount(count + 1)}}>點(diǎn)擊+1</button>
            <div>count is : {count}</div>
            <Counter counter = {double}></Counter>
        </div>
    )
}

子組件用部分屬性useMemo聲明

程序響應(yīng):

    1. <Counter counter = {double}></Counter> 當(dāng)count為2,3的時候勾徽,double發(fā)生變化
  • 2.每次count變化滑凉,子組件都會重新渲染(控制臺打印日志counter),原因是btnClick是箭頭函數(shù)定義的,react頁面更新都會重新渲染子組件

代碼

//函數(shù)組件喘帚,父組件畅姊,子組件
const Counter = memo(function Counter(props) {
    console.log('counter')
    return (
        <div>
            double is : {props.counter}
        </div>
    )
})

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

    const double = useMemo(()=>{
        return count * 2
    }, [count === 2])

    const btnClick = ()=>{
        console.log('click')
    }

    return (
        <div>
            <button onClick={()=>{setCount(count + 1)}}>點(diǎn)擊+1</button>
            <div>count is : {count}</div>
            <Counter counter = {double} onClick={btnClick}></Counter>
        </div>
    )
}

子組件用全部屬性useMemo/useCallback聲明

程序響應(yīng):

    1. <Counter counter = {double}></Counter> 當(dāng)count為2,3的時候吹由,double發(fā)生變化
  • 2.當(dāng)count為2若未,3的時候,子組件會重新渲染(控制臺打印日志counter
    1. const btnClick = useCallback(()=>{console.log('click')}, [])倾鲫, 關(guān)注useCallback第二個參數(shù)粗合,
      ** a.當(dāng)?shù)诙€參數(shù)不設(shè)置,則每次count變化乌昔,子組件都會重新加載隙疚,即使counter = {double}不發(fā)生變化,因?yàn)閎tnClick是首次加載和更新都會重新加載磕道,導(dǎo)致子組件也會重新加載
      ** b.當(dāng)?shù)诙€參數(shù)為[]出現(xiàn)2的現(xiàn)象供屉,原因是子組件的double發(fā)生變化
      ** c.當(dāng)?shù)诙€參數(shù)為[double]出現(xiàn)2的現(xiàn)象,原因是double發(fā)生比變化

代碼

//函數(shù)組件溺蕉,父組件伶丐,子組件
const Counter = memo(function Counter(props) {
    console.log('counter')
    return (
        <div>
            double is : {props.counter}
        </div>
    )
})

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

    const double = useMemo(()=>{
        return count * 2
    }, [count === 2])

    const btnClick = useCallback(()=>{
        console.log('click')
    }, [])

    return (
        <div>
            <button onClick={()=>{setCount(count + 1)}}>點(diǎn)擊+1</button>
            <div>count is : {count}</div>
            <Counter counter = {double} onClick={btnClick}></Counter>
        </div>
    )
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市疯特,隨后出現(xiàn)的幾起案子哗魂,更是在濱河造成了極大的恐慌,老刑警劉巖漓雅,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啡彬,死亡現(xiàn)場離奇詭異羹与,居然都是意外死亡故硅,警方通過查閱死者的電腦和手機(jī)庶灿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吃衅,“玉大人往踢,你說我怎么就攤上這事∨遣悖” “怎么了峻呕?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長趣效。 經(jīng)常有香客問我瘦癌,道長,這世上最難降的妖魔是什么跷敬? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任讯私,我火速辦了婚禮,結(jié)果婚禮上西傀,老公的妹妹穿的比我還像新娘斤寇。我一直安慰自己,他們只是感情好拥褂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布娘锁。 她就那樣靜靜地躺著,像睡著了一般饺鹃。 火紅的嫁衣襯著肌膚如雪莫秆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天悔详,我揣著相機(jī)與錄音镊屎,去河邊找鬼。 笑死伟端,一個胖子當(dāng)著我的面吹牛杯道,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播责蝠,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼党巾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了霜医?” 一聲冷哼從身側(cè)響起齿拂,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肴敛,沒想到半個月后署海,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吗购,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年砸狞,在試婚紗的時候發(fā)現(xiàn)自己被綠了捻勉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡刀森,死狀恐怖踱启,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情研底,我是刑警寧澤埠偿,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站榜晦,受9級特大地震影響冠蒋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乾胶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一抖剿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胚吁,春花似錦牙躺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至半抱,卻和暖如春脓恕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背窿侈。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工炼幔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人史简。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓乃秀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親圆兵。 傳聞我的和親對象是個殘疾皇子跺讯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Hooks 是React的一次革命性升級,本文將對其優(yōu)勢和API進(jìn)行比較全面的解析 為什么要有hooks 在沒有h...
    smartzheng閱讀 935評論 0 5
  • useMemo 一殉农、作用 useMemo 和 memo 作用相同刀脏,都是用來做性能優(yōu)化的,不會影響業(yè)務(wù)邏輯超凳。 mem...
    Lia代碼豬崽閱讀 3,529評論 0 5
  • Hook 是 React 16.8 的新增特性愈污。它可以讓你在不編寫 class 的情況下使用 state 以及其他...
    mora__閱讀 585評論 0 0
  • 一耀态、react新特性 1. context 在一個典型的 React 應(yīng)用中,數(shù)據(jù)是通過 props 屬性自上而下...
    zxhnext閱讀 1,034評論 0 0
  • useMemo 把“創(chuàng)建”函數(shù)和依賴項(xiàng)數(shù)組作為參數(shù)傳入 useMemo暂雹,它僅會在某個依賴項(xiàng)改變時才重新計(jì)算 mem...
    前端家園閱讀 20,459評論 5 24