useMemo, useCallback, useEffect 三者區(qū)別

useEffect

  • useEffect是在DOM改變之后觸發(fā)
  • useEffect可以幫助我們在DOM更新完成后執(zhí)行某些副作用操作
  • 諸如副作用這類的操作屬于 useEffect 的適用范疇

useMemo

  • 父組件將一個 加工后的【值】綁定到頁面,若父組件的其他值發(fā)生變化時,加工的函數(shù)也會跟著渲染多次,會造成性能浪費; useMemo是將函數(shù)的值緩存起來,只有當 useMemo中的第二個參數(shù)狀態(tài)變化時,函數(shù)才重新加載
  • useMemo便是用于緩存該函數(shù)的執(zhí)行結(jié)果,僅當依賴項改變后才會重新計算
修改后如下,注意useMemo緩存的是函數(shù)執(zhí)行的結(jié)果, 只有當[count, price]改變時才會重走一遍

const Parent = () => {
    const [count, setCount] = useState(0);
    const [color,setColor] = useState("");
    const [price,setPrice] = useState(10);
    const handleClick = () => {
        setCount(count + 1);
    }
    const getTotal = useMemo(()=>{
        console.log("getTotal exec ...") 
        return count * price
    },[count, price])
    
    return (<div>
        <div> <input onChange={(e) => setColor(e.target.value)}/></div>
        <div> <input value={price}  onChange={(e) => setPrice(Number(e.target.value))}/></div>
        <div> {count} <button onClick={handleClick}>+1</button></div>
        <div> {getTotal}</div>
    </div>)
}

memo

  • 父組件 text 或 任何 屬性變化都會導(dǎo)致 Child 函數(shù)重新執(zhí)行,所以即使傳入子組件props沒有任何變化,甚至子組件沒有依賴于任何props屬性,都會導(dǎo)致子組件重新渲染
  • 使用memo包裹子組件時,只有props發(fā)生改變子組件才會重新渲染,以提升一定的性能
const Child = memo((props: any) => {
    console.log("子組件更新..."); // 只有當props屬性改變,name屬性改變時,子組件才會重新渲染
    return (
        <div>
            <h3>子組件</h3>
            <div>text:{props.name}</div>
            <div>{new Date().getTime()}</div>
        </div>
    )
})


const Parent = () => {
    const [text, setText] = useState("")
    …… ……
    <Child name ={text}/>
}

useCallback

  • 父組件將一個【方法】傳遞給子組件,若父組件的其他狀態(tài)發(fā)生變化(數(shù)據(jù)改變)時,作為props的函數(shù)也會產(chǎn)生新的實例,導(dǎo)致函數(shù)重新執(zhí)行,子組件也會跟著渲染多次,會造成性能浪費; usecallback是將父組件傳給子組件的方法給緩存下來,只有當 usecallback中的第二個參數(shù)狀態(tài)變化時,子組件才重新渲染
  • useCallback 應(yīng)該搭配 memo 用作優(yōu)化子組件,防止子組件重復(fù)渲染
const Child = memo((props: any) => {
    console.log("子組件更新..."); // 父級Parent函數(shù)有東西變化,Child重新執(zhí)行,handleInputChange已經(jīng)指向新的函數(shù)實例,所以子組件依然會刷新
    return (
        <div>
            <div>text:{props.name}</div>
            <div> <input onChange={props.handleInputChange} /></div>
        </div>
    )
})
const Parent = () => {
    const [text, setText] = useState("")
    const [count, setCount] = useState(0)
    const handleInputChange =useCallback((e) => {
         setText(e.target.value )
    },[]) 
    return (<div>
            …… ……
        <Child name={text} handleInputChange={handleInputChange}/>
    </div>)
}
  • useCallback返回一個函數(shù),當把它返回的這個函數(shù)作為子組件使用時,可以避免每次父組件更新時都重新渲染這個子組件
const renderButton = useCallback(
     () => (
         <Button type="link">
            {buttonText}
         </Button>
     ),
     [buttonText]    // 當buttonText改變時才重新渲染renderButton
);

引用:useMemo, useCallback, useEffect 三者區(qū)別 - 掘金 (juejin.cn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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