欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

六分鐘帶你快速學(xué)會(huì)react中的useMemo

 更新時(shí)間:2022年12月23日 09:59:53   作者:Breeze  
簡(jiǎn)單說(shuō)React.memo()是通過(guò)校驗(yàn)props中的數(shù)據(jù)是否改變的來(lái)決定組件是否需要重新渲染的一種緩存技術(shù),下面這篇文章主要給大家介紹了關(guān)于如何快速學(xué)會(huì)react中useMemo的相關(guān)資料,需要的朋友可以參考下

概念

react 中是通過(guò)一次次的 re-render (重新渲染)保持我們的值及時(shí)的更新到頁(yè)面上的,每次重新渲染都是一次快照,可以把它想象成一張張的照片,在某個(gè)時(shí)刻它應(yīng)該是什么樣子的

useMemo

  • 把創(chuàng)建函數(shù)和依賴數(shù)組項(xiàng)作為參數(shù)傳入 useMemo,它僅僅會(huì)在數(shù)組依賴項(xiàng)中的值改變時(shí)才會(huì)重新計(jì)算值
  • 這種優(yōu)化有助于避免在每次渲染時(shí)都進(jìn)行高開(kāi)銷(xiāo)的計(jì)算
  • useMemo 的函數(shù)在渲染期間執(zhí)行,所以不該在此期間做的操作請(qǐng)去除
  • 如果沒(méi)有提供依賴數(shù)據(jù),每次都會(huì)重新計(jì)算值,相當(dāng)于沒(méi)有優(yōu)化了

栗子

篩選偶數(shù)

以下代碼實(shí)現(xiàn)功能:找出 0count 之間所有的偶數(shù),count 可以動(dòng)態(tài)改變,實(shí)時(shí)渲染在頁(yè)面上,count 改變則會(huì)引起 re-render

import React, { useState } from 'react';

export default () => {
  const [count, setCount] = useState(100);

  const arr = [];
  for (let i = 0; i < count; i++) {
    if (i % 2 === 0) {
      arr.push(i);
    }
  }

  return (
    <>
      <form>
        <label htmlFor="num">Your number:</label>
        <input
          type="number"
          value={count}
          onChange={(event) => {
            // 設(shè)置最大值為 100000
            let num = Math.min(100_000, Number(event.target.value));
            setCount(num);
          }}
        />
      </form>
      <p>
        有{arr.length}偶數(shù)在 0 到 {count} 之間:<span>{arr.join(', ')}</span>
      </p>
    </>
  );
};

每秒獲取時(shí)間刷新頁(yè)面

下面代碼增加了計(jì)時(shí)器,在頁(yè)面顯示實(shí)時(shí)的時(shí)間,這樣頁(yè)面每秒鐘都會(huì) re-render,也會(huì)每秒鐘重新篩選一次偶數(shù)(盡管 count 并沒(méi)有變化)

import React, { useState, useEffect } from 'react';

export default () => {
  const [count, setCount] = useState(100);
  const [curTime, setCurTime] = useState('');

  const useTime = () => {
    useEffect(() => {
      const intervalId = window.setInterval(() => {
        let time = new Date();
        setCurTime(time.toLocaleString());
      }, 1000);

      return () => {
        window.clearInterval(intervalId);
      };
    }, []);

    return curTime;
  };
  const time = useTime();

  const arr = [];
  for (let i = 0; i < count; i++) {
    if (i % 2 === 0) {
      arr.push(i);
    }
  }

  return (
    <>
      <form>
        <div>{time}</div>
        <label htmlFor="num">Your number:</label>
        <input
          type="number"
          value={count}
          onChange={(event) => {
            // 設(shè)置最大值為 100000
            let num = Math.min(100_000, Number(event.target.value));
            setCount(num);
          }}
        />
      </form>
      <p>
        有{arr.length}偶數(shù)在 0 到 {count} 之間:<span>{arr.join(', ')}</span>
      </p>
    </>
  );
};

如何優(yōu)化

那我們需要的是啥,雖然每秒鐘都在重新獲取時(shí)間,但是我們的 count 如果并沒(méi)有變化的話,我們沒(méi)必要去一直重新計(jì)算它的,特別如果 count 的值特別大的時(shí)候,特別如果在一些舊設(shè)備上看著就會(huì)顯得卡頓,極其影響性能 有了 useMemo 就是 so easy 啊

我們來(lái)改造下計(jì)算偶數(shù)地方的代碼:這樣如果 count 不變的情況下,不會(huì)進(jìn)行重復(fù)的計(jì)算,直接使用上次的值

const arr = useMemo(() => {
  const temp = [];
  for (let i = 0; i < count; i++) {
    if (i % 2 === 0) {
      temp.push(i);
    }
  }
  return temp;
}, [count]);

useCallback、React.memo

既然講到 useMemo 了,那么 useCallback、React.memo 也順便說(shuō)下吧,一個(gè)效果的東西,只不過(guò)將返回的值從對(duì)象變成了函數(shù)或者組件

  • React.memo:當(dāng)其作用于函數(shù)式組件并且作為子組件時(shí), 每次父組件更新后, 會(huì)淺對(duì)比傳來(lái)的 props 是否變化, 若沒(méi)變化, 則子組件不更新
  • useCallback:作用和 useMemo 一致,返回一個(gè)函數(shù)

下面看個(gè)小栗子:

// 父組件代碼:一個(gè)計(jì)時(shí)器每秒更新時(shí)間,父組件每秒不停的 re-render,改變 count 值的 onCountChange 函數(shù)傳入子組件
import React, { useState, useEffect, useCallback } from 'react';
import Child from './child';

export default () => {
  const [count, setCount] = useState(100);
  const [curTime, setCurTime] = useState('');

  const useTime = () => {
    useEffect(() => {
      const intervalId = window.setInterval(() => {
        let time = new Date();
        setCurTime(time.toLocaleString());
      }, 1000);

      return () => {
        window.clearInterval(intervalId);
      };
    }, []);

    return curTime;
  };
  const time = useTime();
  const onCountChange = () => {
    setCount((count) => count + 100);
  };
  console.log('re-render-father');

  return (
    <>
      <div>{time}</div>
      <div>{count}</div>
      <Child onCountChange={onCountChange} />
    </>
  );
};

// 子組件代碼,接收 onCountChange 函數(shù),并且用 React.memo 包裹函數(shù)
import React from 'react';

export default React.memo((props: any) => {
  const { onCountChange } = props;
  console.log('re-render-child');

  return (
    <>
      <div
        onClick={() => {
          onCountChange();
        }}
      >
        加100
      </div>
    </>
  );
});

分析一下上面的栗子:

  • 現(xiàn)象:父組件和子組件都會(huì)不停的 re-render
  • 我子組件加了 React.memo ,雖然父組件因?yàn)橛?jì)時(shí)器在不停的 re-render,但是我每次傳入 onCountChange 的函數(shù)都是一樣的啊,不是說(shuō)比較 props 沒(méi)變就不會(huì) re-render 嗎???為啥也會(huì)不停的 re-render 呢

原因:父組件在不停的 re-render 每次都會(huì)重新創(chuàng)建函數(shù),在 js 中雖然兩個(gè)函數(shù)一模一樣,但是不是一個(gè)引用的話就不相等,所以 React.memo 在進(jìn)行淺比較的時(shí)候就認(rèn)為 props 變化了,子組件也會(huì) re-render,造成了無(wú)效優(yōu)化

解決辦法:既然知道了原因所在,那我們?nèi)绾谓鉀Q呢,那就讓它是同一個(gè)函數(shù)不就好了,那就用到了 useCallback 進(jìn)行優(yōu)化

const onCountChange = useCallback(() => {
  setCount((count) => count + 100);
}, []);

或者可以用 useMemo:返回變成函數(shù)即可

const onCountChange = useMemo(() => {
  return () => {
    setCount((count) => count + 100);
  };
}, []);

由此可見(jiàn) useCallback 為 useMemo 的語(yǔ)法糖而已

將函數(shù)用 useCallback 包裹一樣就會(huì)使用緩存的值,不會(huì)重新創(chuàng)建函數(shù),也就不會(huì)重復(fù) re-render 組件了

總結(jié)

  • useMemo 優(yōu)化我們代碼的手段,可以幫助我們使用緩存的值或者函數(shù)減少重復(fù)計(jì)算或者重復(fù)的渲染,優(yōu)化性能
  • useCallback 作用和 useMemo 基本一致
  • useMemo 或者 useCallback 在 React.memo 因?yàn)?props 中因?yàn)橐弥刀У臅r(shí)候可以幫助使用緩存值(同一個(gè)引用),從而在淺比較的時(shí)候不會(huì) re-render

到此這篇關(guān)于快速學(xué)會(huì)react中useMemo的文章就介紹到這了,更多相關(guān)react中的useMemo內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • react-router-domV6嵌套路由實(shí)現(xiàn)詳解

    react-router-domV6嵌套路由實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了react-router-domV6嵌套路由實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • React中使用react-json-view展示JSON數(shù)據(jù)的操作方法

    React中使用react-json-view展示JSON數(shù)據(jù)的操作方法

    react-json-view是一個(gè)用于顯示和編輯javascript數(shù)組和JSON對(duì)象的React組件,本文給大家分享React中使用react-json-view展示JSON數(shù)據(jù)的操作方法,感興趣的朋友一起看看吧
    2023-12-12
  • react?fiber執(zhí)行原理示例解析

    react?fiber執(zhí)行原理示例解析

    這篇文章主要為大家介紹了react?fiber執(zhí)行原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • react通過(guò)組件拆分實(shí)現(xiàn)購(gòu)物車(chē)界面詳解

    react通過(guò)組件拆分實(shí)現(xiàn)購(gòu)物車(chē)界面詳解

    這篇文章主要介紹了react通過(guò)組件拆分來(lái)實(shí)現(xiàn)購(gòu)物車(chē)頁(yè)面的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • 十分鐘帶你快速了解React16新特性

    十分鐘帶你快速了解React16新特性

    這篇文章主要介紹了十分鐘帶你快速了解React16新特性,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • React?Fiber構(gòu)建源碼解析

    React?Fiber構(gòu)建源碼解析

    這篇文章主要為大家介紹了React?Fiber構(gòu)建源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • 一篇文章介紹redux、react-redux、redux-saga總結(jié)

    一篇文章介紹redux、react-redux、redux-saga總結(jié)

    這篇文章主要介紹了一篇文章介紹redux、react-redux、redux-saga總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-05-05
  • React useImperativeHandle處理組件狀態(tài)和生命周期用法詳解

    React useImperativeHandle處理組件狀態(tài)和生命周期用法詳解

    React Hooks 為我們提供了一種全新的方式來(lái)處理組件的狀態(tài)和生命周期,useImperativeHandle是一個(gè)相對(duì)較少被提及的Hook,但在某些場(chǎng)景下,它是非常有用的,本文將深討useImperativeHandle的用法,并通過(guò)實(shí)例來(lái)加深理解
    2023-09-09
  • create-react-app安裝出錯(cuò)問(wèn)題解決方法

    create-react-app安裝出錯(cuò)問(wèn)題解決方法

    這篇文章主要介紹了create-react-app安裝出錯(cuò)問(wèn)題解決方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • 詳解react native頁(yè)面間傳遞數(shù)據(jù)的幾種方式

    詳解react native頁(yè)面間傳遞數(shù)據(jù)的幾種方式

    這篇文章主要介紹了詳解react native頁(yè)面間傳遞數(shù)據(jù)的幾種方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11

最新評(píng)論