useEffect useCallback 和 useMemo
useEffect
useEffect可以帮助我们在DOM更新完成后执行某些副作用操作,如数据获取,设置订阅以及手动更改 React 组件中的 DOM 等
有了useEffect,我们可以在函数组件中实现 像类组件中的生命周期那样某个阶段做某件事情,具有:
componentDidMount
componentDidUpdate
componentWillUnmount
基本用法
useEffect(() => { console.log('这是一个不含依赖数组的useEffect,每次render都会执行!') })
useEffect 规则
没有传第二个参数时,在每次 render 之后都会执行 useEffect中的内容
useEffect接受第二个参数来控制跳过执行,下次 render 后如果指定的值没有变化就不会执行
useEffect 是在 render 之后浏览器已经渲染结束才执行(什么时候会重新渲染呢?在组件初始化的时候,还有就是在和组件绑定的数据发生变化的时候会重新渲染)
useEffect 的第二个参数是可选的,类型是一个数组(数组中的值变化会出发副作用,相当于vue的watch)
根据第二个参数的不同情况,useEffect具有不同作用(不传参数就相当于componentDidMount,只会在初始化的时候执行一次)
useCallback 和 useMemo
都是属于组件性能优化的手段,用来缓存一些复杂的计算结果(useMemo返回值,不经常改变的)和 缓存一些父组件传给子组件的内容,避免父组件每次更新都要重新渲染子组件。
useMemo返回的的是一个值,用于避免在每次渲染时都进行高开销的计算。例:
// 仅当num改变时才重新计算结果
const result = useMemo(() => {
for (let i = 0; i < 100000; i++) {
(num * Math.pow(2, 15)) / 9;
}
}, [num]);
useCallback 和 useMemo 的区别是useCallback返回一个函数,当把它返回的这个函数作为子组件使用时,可以避免每次父组件更新时都重新渲染这个子组件,
const App = ({val}) => {
const [count, setCount] = useState(0)
const onClick = useCallback(() => {
// ...
}, [])
const data = useMemo(() => val, [val])
return (
<>
<button onClick={() => setCount(count+1)}>点我</button>
<OtherComp onClick={onClick} data={data} />
</>
)
}
提示:当我们不知道是否该使用useCallback 和 useMemo 的时候最好不用使用,因为它在初始化渲染的时候,需要保留上次的值,和最新的值对比...首次的开销是比较大的。不然react在设计的时候直接把它包裹在组件中了。useEffect虽然可能会渲染很多次但是在vDom还是很快的。