useMemo/useCallback/React.memo

返回一個(gè) memoized

// useMemo返回一個(gè)值(可以是函數(shù))
const computeExpensiveValue = (a, b) => {
    return a + b;
}
const memoizedValue = useMemo(computeExpensiveValue(a, b), [a, b]);


// useCallbak返回一個(gè)函數(shù)
const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);
  • useMemo和useCallback解決的因函數(shù)更新而渲染自己的問(wèn)題
  • 它僅會(huì)在某個(gè)依賴項(xiàng)改變時(shí)才重新計(jì)算 memoized 值
  • 傳入 useMemo 的函數(shù)會(huì)在渲染期間執(zhí)行
  • 副作用屬于 useEffect 的適用范疇,而不是 useMemo
  • 如果沒(méi)有提供依賴項(xiàng)數(shù)組嘿架,useMemo 在每次渲染時(shí)都會(huì)計(jì)算新的值
  • useCallback(fn, deps) 相當(dāng)于 useMemo(() => fn, deps)瓶珊。

與React.memo的區(qū)別

  • react.memo解決的是因父組件state變化因?yàn)榈淖越M件重復(fù)刷新的問(wèn)題
  • React.memo的用法
function MyComponent(props) {
  
}
function areEqual(prevProps, nextProps) {
  // 手動(dòng)判斷是否需要重新渲染
  // return true不渲染,false則渲染
}
export default React.memo(MyComponent, areEqual);

問(wèn)題

  1. React.memo 第二個(gè)參數(shù)不用的話默認(rèn)就 props 淺比較
  2. React.memo 在跟某些hooks配合使用的情況下會(huì)失效耸彪,例如在組件內(nèi)部使用 useState伞芹,useReduceruseContext 蝉娜,當(dāng) state 或者 context 改變時(shí)唱较,組件還是會(huì)重新渲染
import React, { useState } from "react";
function Child1(props) {
  console.log("執(zhí)行子組件1了");
  return <div>子組件1上的n:{props.value}</div>;
}
function Child2(props) {
  console.log("執(zhí)行子組件2了");
  return <div>子組件2上的m:{props.value}</div>;
}

const MChild1 = React.memo(Child1, () => {
    return false; // 失效
}); // compare失效會(huì)直接導(dǎo)致整個(gè)React.memo失效
const MChild2 = React.memo(Child2);

export default function App() {
  const [n, setN] = useState(0);
  const [m, setM] = useState(10);
  console.log("執(zhí)行最外層盒子了");
  // 這里與是否是箭頭函數(shù)無(wú)關(guān)
  function addM() {
    setM(m + 1);
  }
  // 只要是復(fù)雜類型,都會(huì)渲染
    const test = { a: 134 }; // 如果test是簡(jiǎn)單類型召川,則不會(huì)重復(fù)渲染
  return (
    <>
      <div>
        最外層盒子
        <MChild1 value={n} test={test}/>
        <MChild2 value={m} addM={addM} />
        <button
          onClick={() => {
            setN(n + 1);
          }}
        >
          n+1
        </button>
        <button
          onClick={addM}
        >
          m+1
        </button>
      </div>
    </>
  );
}

問(wèn)題

  1. 自定義的compare函數(shù)失效南缓,導(dǎo)致整個(gè)React.memo失效
  2. App重新執(zhí)行了,它會(huì)修改復(fù)雜數(shù)據(jù)類型的地址荧呐,從而引發(fā)重新渲染
  • useMemo解決addN和addM地址變更引發(fā)的重復(fù)渲染的問(wèn)題
import React, { useState, useMemo, useCallback, memo } from "react";
const Child1 = memo((props) => {
  console.log("執(zhí)行子組件1了");
  return <div>子組件1上的n:{props.value}</div>;
})

const Child2 = memo((props) => {
  console.log("執(zhí)行子組件2了");
  return <div>子組件2上的m:{props.value.m}</div>;
})

export default function App() {
  const [n, setN] = useState(0);
  const [m, setM] = useState({ m: 1 });
  console.log("執(zhí)行最外層盒子了");
  const addN = useMemo(() => {
    return () => {
      setN(n + 1);
    };
  }, [n]);
  const addM = useCallback(() => {
    setM({ m: m.m + 1 });
  }, [m]);
  return (
    <>
      <div>
        最外層盒子
        <Child1 value={n} click={addN} />
        <Child2 value={m} click={addM} />
        <button onClick={addN}>n+1</button>
        <button onClick={addM}>m+1</button>
      </div>
    </>
  );
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末汉形,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子倍阐,更是在濱河造成了極大的恐慌概疆,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件收捣,死亡現(xiàn)場(chǎng)離奇詭異届案,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)罢艾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)楣颠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人咐蚯,你說(shuō)我怎么就攤上這事童漩。” “怎么了春锋?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵矫膨,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我期奔,道長(zhǎng)侧馅,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任呐萌,我火速辦了婚禮馁痴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肺孤。我一直安慰自己罗晕,他們只是感情好济欢,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著小渊,像睡著了一般法褥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上酬屉,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天半等,我揣著相機(jī)與錄音,去河邊找鬼梆惯。 笑死酱鸭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的垛吗。 我是一名探鬼主播凹髓,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼怯屉!你這毒婦竟也來(lái)了蔚舀?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤锨络,失蹤者是張志新(化名)和其女友劉穎赌躺,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體羡儿,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡礼患,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掠归。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缅叠。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖虏冻,靈堂內(nèi)的尸體忽然破棺而出肤粱,到底是詐尸還是另有隱情,我是刑警寧澤厨相,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布领曼,位于F島的核電站,受9級(jí)特大地震影響蛮穿,放射性物質(zhì)發(fā)生泄漏庶骄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一践磅、第九天 我趴在偏房一處隱蔽的房頂上張望瓢姻。 院中可真熱鬧,春花似錦音诈、人聲如沸幻碱。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)褥傍。三九已至,卻和暖如春喇聊,著一層夾襖步出監(jiān)牢的瞬間恍风,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工誓篱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朋贬,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓窜骄,卻偏偏與公主長(zhǎng)得像锦募,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子邻遏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

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