推荐看这两篇文章:
useCallback: juejin.cn/post/684490…
useMemo: juejin.cn/post/684490…
以下是我根据这两篇文章做的笔记,可以不看我写的,但是一定要看以上两篇。
首先,React.memo 和 useMemo 和 useCallback 这三者都属于性能优化的操作,避免不必要的渲染。
React.memo
import React from 'react';
const MemoCom = () => {
return (
<div>
MemoCom.
</div>
);
}
export default React.memo(MemoCom);
React.memo 为高阶组件,只适用于函数组件,不适用于 class 组件。它与 React.pureComponent 相似,默认情况下只会对复杂对象进行浅层比较。
React.memo 只检查 props 变更,如果组件中有 state,那么如果 state 更新也会重新渲染。
将组件包装在 React.memo 中调用,以此通过记忆组件渲染结果的方式来提高组件的性能表现。
如果想要控制对比过程,可以自定义比较函数,然后传入 React.memo 的第二个参数。
import React from 'react'
const MemoCom = props => {
// 组件内容
}
const equal = (prevProps, nextProps) => {
// 通过对比返回 true 或 false
}
export default React.memo(MemoCom, equal)
总结:也就是说,使用了 React.memo 的组件,当 props 和 state 没有发生变化时,就不会重新渲染。
useCallback
import React, { useCallback, useState } from 'react';
const useCallbackCom = () => {
const [num] = useState(0)
const getNum = useCallback(() => {
console.log(num);
}, [num])
return (
<div>
useCallback.
</div>
);
}
export default useCallbackCom;
useCallback 返回一个回调函数,
useCallback(操作函数, 依赖项),如果依赖性没有发生变化,直接返回缓存的值,如果依赖项发生变化时才会重新执行这个函数,类似于 shouldComponentUpdate。
总结:也就是说,useCallback 用于缓存一个函数,使用了 useCallback 的函数,只有依赖的变量发生变化时才更新,否则就会使用缓存的值。
useMemo
import React, { useMemo, useState } from 'react';
const useMemoCom = () => {
const [num] = useState(0)
const getNum = useMemo(() => {
let result
// 包含了大量的计算逻辑,最后得出一个结果
// 大量计算中
return result
}, [num])
return (
<div>
useMemoCom.
</div>
);
}
export default useMemoCom;
useMemo 函数会在渲染期间执行,所以不要在这个函数中执行副作用,如果存在副作用,就用 useEffect。
useMemo(操作函数, 依赖项)如果没有传入第二个依赖项,那么每次渲染时都会执行。
useMemo 完全可以替代 useCallback,因为 useMemo 可以返回一个函数,那么 useMemo 就会把这个函数当作返回值存储起来,例如:useMemo(() => () => {// 一些代码}, [依赖项])
总结:也就是说,useMemo 用于缓存函数的返回值,当依赖项没有发生变化时,依然使用这个被缓存的返回值。
useCallback 不会执行第一个参数函数,而是将函数返回;useMemo 会执行第一个参数函数,将函数的执行结果返回。