在函数式组件开发过程中,我们会发现任何一个state值发生变化,组件都会重新渲染。当我们在一些特殊场景需要限定某个state值发生改变再进行渲染或者说项目越来越复杂需要进行渲染优化时,我们就会用到两个用于性能优化的hooks:useMemo和useCallback。今天我们先讲useMemo。
一、基础用法
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a,b])
useMemo接受两个参数,第一个为回调函数,第二个参数是依赖的数组。即只有当a或者b发生改变后,则执行useMemo里的回调函数,注意useMemo返回的是计算的结果值。
二、具体案例
组件中有两个state,分别是count(数字)和user(操作人)。我们希望使用useMemo函数来实现一个效果:oprationInfo(返回一个dom)只在user值变更的时候才进行渲染。
在以下案例中,仅当user值发生改变时,operationInfo里面返回的dom节点才会进行重新渲染,除此外,其它dom节点无论是count和user哪个值发生了改变,都会发生重渲染。
import React, { useState, useMemo } from 'react';
import './index.less';
const UseMemoExample: React.FC = () => {
const [count, setCount] = useState<number>(0);
const [user, setUser] = useState<string>('小红');
const oprationInfo = useMemo(() => {
return (
<p>
{console.log('只有当依赖项(即user)变更时才会打印:', user, count)}
当前操作人--使用useMemo:{user}
<b>(数字:{count})</b>
</p>
);
}, [user]);
return (
<div className="box-wrap">
{console.log('每次有状态变更都会打印:', count)}
<p>当前数字:{count}</p>
<p>
当前操作人:{user}
<b>(数字:{count})</b>
</p>
{oprationInfo}
<button onClick={() => setCount(count + 1)}>数字递增</button>
<button onClick={() => setUser('小明')}>更改操作人</button>
</div>
);
};
export default UseMemoExample;
三、效果展示
刚进入页面时,从控制台打印可以看出,useMemo函数会在组件第一次渲染的时候会执行一次。
结合页面及控制台打印效果,当我们不断点击<数字递增>按钮时,除了标注使用useMemo的数字值没有发生改变,上面两个地方的数值都在不断增加1。当我们增加到5时,点击<更改操作人>按钮,标注使用useMemo的那一栏除了名字发生了改变,数字的值也更改为了5,控制台也打印了相关内容。这说明只有user值发生改变,useMemo函数才会进行渲染。
试想下,举个例子,在开发过程中,父组件可能会存在某个state值频繁变化,而每次这个值都会导致和此值无关的子组件进行重渲染,这是没有必要且消耗性能的事情,这时我们使用useMemo是不是就能解决这类型的性能问题了呢。
感谢您读完本文!如果本文对您有帮助,请点个赞呗,您的点赞是对我最大的支持和认可!
我的公众号:大前端教程,欢迎关注,会定期更新前端知识,希望能帮到您。