react-useMemo/useCallback/memo使用

react提供useMemo/useCallback/memo方法,提高頁(yè)面刷新效率。若組件依賴的屬性沒(méi)有發(fā)送變化,組件可以不刷新。以下提供兩個(gè)場(chǎng)景的具體使用

單組件內(nèi)使用

使用語(yǔ)法

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

useMemo

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

  • useMemo第二個(gè)參數(shù)不設(shè)置
  • 代碼表現(xiàn):每次點(diǎn)擊點(diǎn)擊+1,控制臺(tái)打印double,同時(shí)標(biāo)簽Double每次刷新
  • 代碼解析:useMemo第二個(gè)參數(shù)不設(shè)置,頁(yè)面首次加載和頁(yè)面更新,都會(huì)重新加載<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è)置第二個(gè)參數(shù)為[],首次加載更新)

  • useMemo第二個(gè)參數(shù)設(shè)置為[],這組件只會(huì)在頁(yè)面首次加載更新,類似類組件的componentDidMount
  • 代碼表現(xiàn):頁(yè)面首次加載,控制臺(tái)打印double;每次點(diǎn)擊點(diǎn)擊+1,控制臺(tái)打印無(wú)打印日志,同時(shí)標(biāo)簽Double始終為0
  • 代碼解析:useMemo第二個(gè)參數(shù)設(shè)置[],<div>Double is :{double}</div>只有在首次頁(yè)面加載,即double變化了,也不會(huì)改變標(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è)置第二個(gè)參數(shù)為[count===2])

  • useMemo第二個(gè)參數(shù)設(shè)置為[count===2]
  • 代碼表現(xiàn):頁(yè)面首次加載,控制臺(tái)打印double;點(diǎn)擊點(diǎn)擊+1,當(dāng)count=2,count=3的時(shí)候控制臺(tái)打印double,同時(shí)標(biāo)簽<div>Double is :{double}</div>更新兩次,分別為Double is :4Double is :6
  • 代碼解析:useMemo第二個(gè)參數(shù)設(shè)置[count===2],表示當(dāng)count===2的時(shí)候才會(huì)更新組件,count1,2,3對(duì)應(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):

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

操作:

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

子組件沒(méi)用memo聲明

程序響應(yīng):

    1. <Counter counter = {double}></Counter> 當(dāng)count為2,3的時(shí)候,double發(fā)生變化
  • 2.每次count變化,子組件都會(huì)重新渲染(控制臺(tái)打印日志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的時(shí)候,double發(fā)生變化
  • 2.當(dāng)count為2,3的時(shí)候,子組件會(huì)重新渲染(控制臺(tái)打印日志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的時(shí)候,double發(fā)生變化
  • 2.每次count變化,子組件都會(huì)重新渲染(控制臺(tái)打印日志counter),原因是btnClick是箭頭函數(shù)定義的,react頁(yè)面更新都會(huì)重新渲染子組件

代碼

//函數(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的時(shí)候,double發(fā)生變化
  • 2.當(dāng)count為2,3的時(shí)候,子組件會(huì)重新渲染(控制臺(tái)打印日志counter
    1. const btnClick = useCallback(()=>{console.log('click')}, []), 關(guān)注useCallback第二個(gè)參數(shù),
      ** a.當(dāng)?shù)诙€(gè)參數(shù)不設(shè)置,則每次count變化,子組件都會(huì)重新加載,即使counter = {double}不發(fā)生變化,因?yàn)閎tnClick是首次加載和更新都會(huì)重新加載,導(dǎo)致子組件也會(huì)重新加載
      ** b.當(dāng)?shù)诙€(gè)參數(shù)為[]出現(xiàn)2的現(xiàn)象,原因是子組件的double發(fā)生變化
      ** c.當(dāng)?shù)诙€(gè)參數(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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容