preface

Hook has been used for a while, but useCallback and useMemo are not silly (although they can be equivalent to each other to some extent) and the specific use scenarios, so we have to sort it out.

useCallback

const memoizedCallback = useCallback(
  (a)= > {
    doSomething(a, b);
  },
  [a, b],
); Copy the code

Returns a memoized callback function. (Cache function)

use

Without useCallback, the fetchData function will always be executed:

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

export default function App() {
  const [data, setData] = useState(null)
  const [manualRendering, setManualRendering] = useState(1)
  const handleChange = (a)= > {  setManualRendering(manualRendering + 1)  }   const fetchData = async() = > { console.log('I'm a function, I'm being executed again. ')  const res = await fetch(`https://jsonplaceholder.typicode.com/users`)  setData(res)  }  useEffect((a)= > {  fetchData()  }, [fetchData]) // fetchData is executed only once   return (  <div className='App'>  <h1>Hello Hooks</h1>  <button onClick={handleChange}>Re-render</button>  </div>  ) }  Copy the code

With useCallback, the fetchData function will not always be executed, or will be executed again against the array of dependencies:

// Need to introduce useCallback or use react.usecallback directly (but not recommended)

  // const fetchData = async () => {
  // console.log(' I am a function, I am executed again. ')
  // const res = await fetch(`https://jsonplaceholder.typicode.com/users`)
 // setData(res)  // }   const fetchData = useCallback(async() = > { console.log('I'm a function, I'm being executed again. ')  const res = await fetch(`https://jsonplaceholder.typicode.com/users`)  setData(res)  }, []) // The array of dependencies can be added at will. Copy the code

useMemo

const memoizedValue = useMemo((a)= > computeExpensiveValue(a, b), [a, b]);
Copy the code

Returns a memoized value. (Cache value)

use

ComputeExpensiveValue will always be executed without useMemo:

import React, { useState } from 'react'
import "./styles.css";

export default function App() {
  const [manualRendering, setManualRendering] = useState(1)
  // Assume a very complex calculation  const computeExpensiveValue = (a)= > {  console.log('I'm a value, AND I've been calculated. ')  let newValue = 1  for (let i = 1; i < 100; i++) {  newValue = newValue * i  }  return newValue  }   const handleChange = (a)= > {  setManualRendering(manualRendering + 1)  }   const noMemoData = computeExpensiveValue()   return (  <div className='App'>  <h1>Hello Hooks</h1>  <h2>{noMemoData}</h2>  <button onClick={handleChange}>Re-render</button>  </div>  ) }  Copy the code

Click the button frequently and the complex function computeExpensiveValue will always execute:

With useMemo, the complex function computeExpensiveValue will not always be executed, or it will be executed again as an array of dependencies:

// Need to introduce useMemo or use react.usemo directly (but not recommended)

// const noMemoData = computeExpensiveValue()
const useMemoData = useMemo((a)= > computeExpensiveValue(), []) // The array of dependencies can be added at will.
Copy the code

conclusion

  • To some extent, the two are related to each other, and to some extent they are equivalent to each other:

    UseCallback (fn, deps) equals useMemo(() => fn, deps).

  • The above is just a simple understanding of useCallback and useMemo, not all cases need to add useCallback and useMemo, unreasonable place to add will increase performance costs.