亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

React?中?memo?useMemo?useCallback?到底該怎么用

 更新時間:2022年10月22日 08:38:13   作者:YinJie…  
在React函數(shù)組件中,當(dāng)組件中的props發(fā)生變化時,默認(rèn)情況下整個組件都會重新渲染。換句話說,如果組件中的任何值更新,整個組件將重新渲染,包括沒有更改values/props的函數(shù)/組件。在react中,我們可以通過memo,useMemo以及useCallback來防止子組件的rerender

React.memo怎么用

React.memo()是一個高階組件 (HOC),它接收一個組件A作為參數(shù)并返回一個組件B,如果組件B的 props(或其中的值)沒有改變,則組件 B 會阻止組件 A 重新渲染 。

下面我們看一個示例:

const ParentComponent = () => {
  const [ count, setCount ] = useState(0);
  const handleParent = () => {
    console.log('clicked ParentComponent');
    setCount(preCount => preCount + 1);
  };
  return (
    <div>
      <div onClick={handleParent}>父組件,點(diǎn)擊了{(lán)count}次</div>
      <ChildrenComponent />
    </div>
  );
};
const ChildrenComponent = () => {
  console.log('ChildrenComponent rending');
  return <div>我是子組件</div>;
};

點(diǎn)擊父組件:

可以看到控制臺中輸出了子組件里的打印,表示子組件 rerender 了,如果子組件中有龐大的 dom 結(jié)構(gòu)和計(jì)算,那是非常消耗性能的事,通過 memo 我們可以對比 render 前后的 prop 變化,如果沒有變化就不會重新 render 子組件:

const ChildrenComponent = memo(() => {
  console.log('ChildrenComponent rending');
  return <div>我是子組件</div>;
});

把子組件通過 memo 包裹后就不會因?yàn)楦附M件更新導(dǎo)致的 render 了

React.useMemo怎么用

React.memo() 是一個 HOC,而 useMemo() 是一個 React Hook。 使用 useMemo(),我們可以返回記憶值來避免函數(shù)的依賴項(xiàng)沒有改變的情況下重新渲染。并且可以避免在每次渲染時都進(jìn)行高開銷的計(jì)算的優(yōu)化的策略。

   const sum = ()=>{
      return a+b
   }
   const result = useMemo(()=>{sum()},[a,b])
   // 只有在a或者b的值變化時才會觸發(fā)sum函數(shù)執(zhí)行

React.memo()和useMemo()的主要區(qū)別

從上面的例子中,我們可以看到 React.memo()useMemo() 之間的主要區(qū)別:

  • React.memo() 是一個高階組件,我們可以使用它來包裝我們不想重新渲染的組件,除非其中的 props 發(fā)生變化
  • useMemo() 是一個 React Hook,我們可以使用它在組件中包裝函數(shù)。 我們可以使用它來確保該函數(shù)中的值僅在其依賴項(xiàng)之一發(fā)生變化時才重新計(jì)算

雖然 memoization 似乎是一個可以隨處使用的巧妙小技巧,但只有在絕對需要這些性能提升時才應(yīng)該使用它。 Memoization 會占用運(yùn)行它的機(jī)器上的內(nèi)存空間,因此可能會導(dǎo)致意想不到的效果。

React.useCallback怎么用

我們看一下下面這個示例:

const ParentComponent = () => {
  const [ count, setCount ] = useState(0);
  const [ childCount, setChildCount ] = useState(0)
  const handleChildren = () => {
    console.log('clicked ChildrenComponent');
    setChildCount(preCount => preCount + 1)
  };
  const handleParent = () => {
    console.log('clicked ParentComponent');
    setCount(preCount => preCount + 1);
  };
  return (
    <div>
      <div onClick={handleParent}>父組件,點(diǎn)擊了{(lán)count}次</div>
      <ChildrenComponent handleChildren={handleChildren} data={childCount}/>
    </div>
  );
};
const ChildrenComponent = memo(({ handleChildren, data }) => {
  console.log('ChildrenComponent rending', data);
  return <div onClick={handleChildren}>ChildrenComponent,子組件被點(diǎn)擊了{(lán)data}次 </div>;
});

在上面的例子中,我們把子組件通過 React.memo 包起來了,希望在父組件更新的時候,子組件不會 再次render,那么會和我們想的一樣嗎?

當(dāng)點(diǎn)擊父組件時,子組件再次 render 了, 因?yàn)樽咏M件的 prop 傳入了有函數(shù) handleChildren ,當(dāng)點(diǎn)擊父組件時更改了 state 值導(dǎo)致父組件重新 render,那么原來的 hanldeChildren 函數(shù)和更新后的 hanldeChildren 顯然處在不同的執(zhí)行環(huán)境中,他們并不是一個函數(shù),在內(nèi)存中不是同一個引用地址,所以就導(dǎo)致了 memo 的包裹無效,因?yàn)?prop 改變了。

useCallback 需要傳入兩個參數(shù)

  • callback(僅僅是個函數(shù)),把要做事情的函數(shù)放在callback函數(shù)體內(nèi)執(zhí)行
  • deps 要做事情的函數(shù)需要引入的外部參數(shù)或者是依賴參數(shù)
  const handleChildrenCallback = useCallback(() => {
    handleChildren();
  }, []);// 咱們不需要就不要傳入

useCallback 返回一個 memoized 回調(diào)函數(shù)。在依賴參數(shù)不變的情況下,返回的回調(diào)函數(shù)是同一個引用地址

注意 每當(dāng)依賴參數(shù)發(fā)生改變useCallback就會自動重新返回一個新的 memoized 函數(shù)(地址發(fā)生改變)

上面就是沒有使用 useCallBack 的使用場景,現(xiàn)在我們知道了,把要傳遞的函數(shù)參數(shù)通過 useCallBack 包裹一層,這樣返回的回調(diào)函數(shù)就是同一個引用地址,這樣子組件就不會 rerender 了:

 const handleChildren = useCallback(() => {
    console.log('clicked ChildrenComponent');
    setChildCount(preCount => preCount + 1)
  }, [setChildCount]);

現(xiàn)在在點(diǎn)擊父組件后,子組件就不會再 rerender 了。

大伙現(xiàn)在應(yīng)該明白了useCallback的作用了,它主要用來配合memo用于優(yōu)化子組件的渲染次數(shù)

memo與useMemo及useCallback的區(qū)別

  • memo用來優(yōu)化函數(shù)組件的重復(fù)渲染行為,針對的是一個組件
  • useMemo返回一個memoized的值
  • 本質(zhì)都是用同樣的算法來判定依賴是否發(fā)生改變,繼而決定是否觸發(fā)memo或者useMemo中的邏輯,利用memo就可以避免不必要的重復(fù)計(jì)算,減少資源浪費(fèi)
  • useCallback返回一個memoized的函數(shù)

防止不必要的 effect

如果一個值被 useEffect 依賴,那它可能需要被緩存,這樣可以避免重復(fù)執(zhí)行 effect。

const Component = () => {
  // 在 re-renders 之間緩存 a 的引用
  const a = useMemo(() => ({ test: 1 }), []);
  useEffect(() => {
    // 只有當(dāng) a 的值變化時,這里才會被觸發(fā)
    doSomething();
  }, [a]);
  // the rest of the code
};

useCallback 同理:

const Component = () => {
  // 在 re-renders 之間緩存 fetch 函數(shù)
  const fetch = useCallback(() => {
    console.log('fetch some data here');
  }, []);
  useEffect(() => {
    // 僅fetch函數(shù)的值被改變時,這里才會被觸發(fā)
    fetch();
  }, [fetch]);
  // the rest of the code
};

當(dāng)變量直接或者通過依賴鏈成為 useEffect 的依賴項(xiàng)時,那它可能需要被緩存。這也是 useMemo 和 useCallback 得基本用法之一。

到此這篇關(guān)于React 中 memo useMemo useCallback 到底該怎么用的文章就介紹到這了,更多相關(guān)React memo useMemo useCallback內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React和Vue實(shí)現(xiàn)文件下載進(jìn)度條

    React和Vue實(shí)現(xiàn)文件下載進(jìn)度條

    本文主要介紹了React和Vue實(shí)現(xiàn)文件下載進(jìn)度條,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • react使用.env文件管理全局變量的方法

    react使用.env文件管理全局變量的方法

    本文主要介紹了react使用.env文件管理全局變量的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 基于React和antd實(shí)現(xiàn)自定義進(jìn)度條的示例代碼

    基于React和antd實(shí)現(xiàn)自定義進(jìn)度條的示例代碼

    在現(xiàn)代 Web 開發(fā)中,進(jìn)度條是一種常見且實(shí)用的 UI 組件,用于直觀地向用戶展示任務(wù)的完成進(jìn)度,本文將詳細(xì)介紹如何使用 React 來構(gòu)建一個自定義的進(jìn)度條,它不僅能夠動態(tài)展示進(jìn)度,還具備額外的信息提示功能,需要的朋友可以參考下
    2025-03-03
  • React 三大屬性之state的使用詳解

    React 三大屬性之state的使用詳解

    這篇文章主要介紹了React 三大屬性之state的使用詳解,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下
    2021-04-04
  • React之如何在Suspense中優(yōu)雅地請求數(shù)據(jù)

    React之如何在Suspense中優(yōu)雅地請求數(shù)據(jù)

    Suspense 是 React 中的一個組件,直譯過來有懸掛的意思,能夠?qū)⑵浒漠惒浇M件掛起,直到組件加載完成后再渲染,本文詳細(xì)介紹了如何在Suspense中請求數(shù)據(jù),感興趣的小伙伴可以參考閱讀本文
    2023-04-04
  • 三分鐘搞懂react-hooks及實(shí)例代碼

    三分鐘搞懂react-hooks及實(shí)例代碼

    React?Hooks是今年最勁爆的新特性真的毫不夸張。如果你也對react感興趣,或者正在使用react進(jìn)行項(xiàng)目開發(fā),請抽出點(diǎn)時間閱讀下此文
    2022-03-03
  • react中涉及的增加,刪除list方式

    react中涉及的增加,刪除list方式

    這篇文章主要介紹了react中涉及的增加,刪除list方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • React中setTimeout獲取不到最新State值的原因及解決方案

    React中setTimeout獲取不到最新State值的原因及解決方案

    在 React 開發(fā)中,我們常常需要在異步操作中訪問組件的 State,然而,由于 React 的閉包機(jī)制和異步更新特性,setTimeout?中可能會獲取到過時的 State 值,本文將深入解析這一現(xiàn)象的原因,并提供多種解決方案,需要的朋友可以參考下
    2025-10-10
  • react-dnd?API拖拽工具詳細(xì)用法示例

    react-dnd?API拖拽工具詳細(xì)用法示例

    這篇文章主要為大家介紹了react-dnd?API拖拽工具的詳細(xì)用法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • react項(xiàng)目引入scss的方法

    react項(xiàng)目引入scss的方法

    這篇文章主要介紹了react項(xiàng)目引入scss的方法,本文給大家介紹了React pwa的配置方法,通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04

最新評論