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.