The premise
- Both take two arguments fn, deps, and return to cache in order to avoid unnecessary rendering.
- The difference is that useMemo returns the result of a function run. UseCallback returns a function:
useCallback(fn, deps) --> useMemo(() => fn, deps);
Copy the code
- That is, useMemo will execute the incoming function and cache the result. UseCallback caches the entire function, depending on the second parameter.
- The second parameter is the same as in useEffect.
example
// useMemo const [count, setCount] = useState(1); Const Nodes = useMemo(() => {return (<em style={{paddingRight: '30px'}}> query {count}</em>)}, [count]); Const getNodes = useCallback(() => {return (<em style={{paddingRight: '30px'}}> query {count}</em>)}, [count]); return ( <div> <div onClick={() => setCount(count + 1)}>{count}</div> { nodes } { getNodes() } </div> )Copy the code
- The above example nodes has the same effect as getNodes.
- Of course, this is not to say that the two uses are interchangeable, they are used in different situations:
function Child({getCount}) { return ( <div>{getCount()}</div> ) }; function Parent() { const [count, setCount] = useState(1); const [number, setNumber] = useState(1); const getCount = useCallback(() => { return Array.from({length: count * 100}, (v, i) => i).reduce((a, b) => a+b) }, [count]); Return (<div> <Child getCount={getCount} number={number} /> <div onClick={() => setCount(count + 1)}> {count} < / div > < div onClick = {() = > setNumber (number + 1)} > Numbers: {number} < / div > < / div >)}Copy the code
1. When the “number” button is clicked, both sunCount and getCount will not be re-rendered. If useCallback is not used, both sunCount and getCount will be re-rendered. The child component is also rerendered because the function is regenerated as a result of the update of the parent component and the function reference passed to the child component changes.
Function Child({getCount, number}) {const curNumber = useMemo(function () {console.log('--number --') return <h4> {number}</h4> }, [number]); return ( <div>{getCount()}{curNumber}</div> ) }; function Parent() { const [count, setCount] = useState(1); const [number, setNumber] = useState(1); const getCount = useCallback(() => { return Array.from({length: count * 100}, (v, i) => i).reduce((a, b) => a+b) }, [count]); Return (<div> <Child getCount={getCount} number={number} /> <div onClick={() => setCount(count + 1)}> {count} < / div > < div onClick = {() = > setNumber (number + 1)} > Numbers: {number} < / div > < / div >)}Copy the code
- Click the “calculate” button, Child is re-rendered, but curNumber is not.