useCallBack和useMemo的用法


https://juejin.cn/post/6844904101445124110#heading-6

useCallback 的作用

useCallback是用來優化性能的,

但是,如果不了解它是怎么優化性能的,建議還是不要用了,因為,容易出現bug。

useCallback返回一個函數,只有在依賴項變化的時候才會更新(返回一個新的函數)。

import React, { useState, useCallback } from 'react';
import Button from './Button';

export default function App() {
  const [count1, setCount1] = useState(0);
  const [count2, setCount2] = useState(0);
  const [count3, setCount3] = useState(0);

  const handleClickButton1 = () => {setCount1(count1 + 1)};

  const handleClickButton2 = useCallback(() => {
    setCount2(count2 + 1);
  }, [count2]);

  return (
    <div>
      <div>
        <Button onClick={handleClickButton1}>Button1</Button>
      </div>
      <div>
        <Button onClick={handleClickButton2}>Button2</Button>
      </div>
      <div>
        <Button  onClick={() => {setCount3(count3 + 1);     }}>
          Button3
        </Button>
      </div>
    </div>
  );
}


鏈接:https://juejin.cn/post/6844904101445124110
// Button.jsx
import React from 'react';

const Button = ({ onClickButton, children }) => {
  return (
    <>
      <button onClick={onClickButton}>{children}</button>
      <span>{Math.random()}</span>
    </>
  );
};

export default React.memo(Button);

在案例中可以分別點擊Demo中的幾個按鈕來查看效果:

  • 點擊 Button1 的時候只會更新 Button1 和 Button3 后面的內容;
  • 點擊 Button2 會將三個按鈕后的內容都更新;
  • 點擊 Button3 的也是只更新 Button1 和 Button3 后面的內容。

經過useCallback優化后的 Button2 是點擊自身時才會變更(更新),其他的兩個只要父組件更新后都會變更(這里Button1 和 Button3 其實是一樣的,無非就是函數換了個地方寫)。

注:Button組件里面的React.memo這個方法,會對props做一個淺層比較,如果props沒有發生改變,則不會重新渲染此組件。沒有用useCallback包括的函數,每次都會重新聲明一個新的方法,新的方法盡管和舊的方法一樣,但是依舊是兩個不同的對象,React.memo對比后發現對象props改變,就重新渲染了。

用useCallback包括的函數,根據依賴是否發生變化,才會決定是否返回一個新的函數,如果沒有變化,就會返回上一次緩存的函數。

const [count1, setCount1] = useState(0);
const [count2, setCount2] = useState(0);

const handleClickButton1 = () => {
  setCount1(count1 + 1)
};
const handleClickButton2 = useCallback(() => {
  setCount2(count2 + 1)
}, [count2]);

return (
  <>
    <button onClick={handleClickButton1}>button1</button>
    <button onClick={handleClickButton2}>button2</button
  </>
)

上面這種寫法在當前組件重新渲染時 handleClickButton1 函數會重新渲染,handleClickButton2 useCallback 里面的函數也會重新渲染。反而加了 useCallback ,在執行的時候還多了 useCallback 中對 count2 的一個比較邏輯。

 useCallback 是要配合子組件的 shouldComponentUpdate 或者 React.memo 一起來使用的,否則就是反向優化,這就是前面說的bug。

useMemo 的作用

useMemo是在render期間執行的。所以不能進行一些額外的副操作,比如網絡請求等。

傳遞一個創建函數和依賴項,創建函數會需要返回一個值,只有在依賴項發生改變的時候,才會重新調用此函數,返回一個新的值。

沒有用useMemo

// ...
const [count, setCount] = useState(0);

const userInfo = {
  // ...
  age: count,
  name: 'Jace'
}

return <UserCard userInfo={userInfo}>

 

用了useMemo

// ...
const [count, setCount] = useState(0);

const userInfo = useMemo(() => {
  return {
    // ...
    name: "Jace",
    age: count
  };
}, [count]);

return <UserCard userInfo={userInfo}>

第一段沒有用useMemo的代碼,userInfo 每次都將是一個新的對象,無論 count 發生改變沒,都會導致 UserCard 重新渲染,而下面的則會在 count 改變后才會返回新的對象。

怎么用useMemo表示useCallback

useCallback(fn,[m]);

等價於

useMemo(() => fn, [m]);

 

結語

useCallback緩存的是函數,useMemo 緩存的是函數的返回就結果。

useCallback 是來優化子組件的,防止子組件的重復渲染。

useMemo 可以優化當前組件也可以優化子組件,優化當前組件主要是通過 memoize 來將一些復雜的計算邏輯進行緩存。當然如果只是進行一些簡單的計算也沒必要使用 useMemo。

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM