React 如何使用 memo、useMemo、useCallBack?
React.memo 的作用是什么?
简单来讲,就是父组件的 state 发生变化后,父组件本身(函数式组件)会重新执行一遍,其子组件也会重新执行一遍
父组件
js
// 父组件里定义了一个 count 计数器
const [count, setCount] = useState(0);
return (
<>
{/* 父组件里每次点击按钮,count 都会 + 1 */}
<button onClick={() => setCount(count + 1)}>加 1</button>
{/* 纯 UI 组件,又称傻瓜组件,哈哈哈 */}
<Test />
</>
);然后 Test 组件内部:
js
function Test(props:any) {
console.log('我执行了');
return <button>UI</button>
}
export default Test可以看到,每次点击按钮,控制台都会打印一次我执行了
如果在 Test 组件内部使用 memo,那么我执行了这句话只会打印一次。
js
// export default Test
export default React.memo(Test)可是在实际中,很少会用到傻瓜组件,就以这个 Test 组件为例,还可能接收一些 props 参数。当 props 改变时,子组件毫无疑问会重新渲染。如果继续使用 React.memo,它会判断新的 props 和旧的 props 是否相同,如果相同就不会执行子组件函数,否者会再次执行。
比如下面这种 Test 组件就不会重新渲染:
js
<Test suibian={1} />再下面这种就会重新渲染:
js
<Test suibian={{a: 1}} />总结来说,memo 的作用就是当 props 发生改变时,组件才会重新渲染,否则使用缓存的渲染结果。
useMemo 的作用是什么?
字面意思,就是使用缓存。
看下面父组件里的代码,当我们只是改变 count 的值时,name 没有变,但 Test 组件依旧会重新渲染。
js
const [count, setCount] = useState(0);
const [name, setName] = useState('joy')
const data = {
name
}
return (
<>
<button onClick={() => setCount(count + 1)}>加 1</button>
<Test suibian={data} />
</>
);使用 useMemo,即使 count 改变 Test 组件也只会渲染一次了。
js
const data = useMemo(() => {
return {
name
}
}, [name])这里可能会有人好奇了,如果第二个参数是空数组或者不传会怎么样?
若是空数组,即使 count 改变,data 永远都是第一次初始的值。
若是不传,那么 useMemo 就相当于没使用一样,没起到任何缓存效果。
还有一种情况,若第二个参数传的是表达式,会怎么样呢?
js
const data = useMemo(() => {
return {
name
}
}, [5 === count])会在 count === 5 的时候,data 会刷新一般,然后 Test 组件又重新渲染了。
总结来说,useMemo 就是只有第二个参数发生改变时才会重新执行回调。
useCallBack 的作用是什么?
它就是 useMemo 的语法糖,第一个参数只能是函数类型。
js
const goFn = useCallback(() => {
console.log(name);
}, [name])最后
还得在实际中多运用,才能游刃有余,代码写得越来越顺畅,别人的代码也能看懂了。