useCallback是用来帮忙缓存函数的,当依赖项没有发生变化时,返回缓存的指针,而props涉及到复杂对象类型都是通过指针来传递到。
多用于回调函数,在某个依赖项改变时才会更新。当你把回调函数传递给经过优化的并使用引用相等性去避免非必要渲染的子组件是非常有用的。
代码示例:
父组件:
import { useEffect, useState, useCallback } from 'react'
import { Space, Table, Tag, Button } from 'antd'
import Optimize from './component/Optimize';
import PromiseOpt from './component/PromiseOpt';
const Home: React.FC = () => {
const [ count, setCount ] = useState<number>(0)
const memoSetCount = useCallback((count: number)=>setCount(count),[])
return <>
<div>
<h1>{count}</h1>
<Optimize setCount={memoSetCount} count={count} />
</div>
</>
}
export default Home
子组件:
import { useEffect } from 'react'
import { Button } from 'antd'
import React from 'react'
const Optimize: React.FC<{
setCount?: (count: number) => void;
count?: number;
}> = React.memo((props) => {
const { setCount, count } = props
// 在这里如果不是设置了监听对象(count),那么这个useEffect是没有效果的,只执行了一次
useEffect(() => {
console.log('加载了吗?')
}, [count])
return <>
我是一个异步的要缓存的插件
<h1>{count}</h1>
<Button onClick={() => setCount((count)=>count+1)}>点击+1</Button>
</>
})
export default Optimize
注:在父组件中传递到子组件内,子组件如果不使用React.memo那么callBack此时是没什么作用的,甚至页面的useEffect的执行次数非常多,那么必然会导致页面增加了渲染负担,我们在子组件内使用了memo后,memo那的确减少了页面组件内的渲染,起到了一定的优化作用。如果不设置useEffect的第二参数监听count的话,无论count改不改变,那么useEffect也只会执行一次。
React.memo要和callBack一起搭配使用。
memo是一个高阶函数,同样接收两个参数,第一个参数为组件,第二个参数为函数,函数返回true的话组件将不更新,返回false组件将会更新