上次我分享了关于 useCallback的相关内容,有兴趣的可以去看一下,并且也欢迎大家对我的文章提出问题
组件涉及到的优化方式
- shouldComponentUpdate、PureComnent、
- React.memo、
- useMemo、
- useCallback
- useReducer
- context
- useDeferredValue
为什么我们需要去优化React组件?,React在组件的渲染上会有什么问题?
- React组件有个特性,在不进行优化处理时父组件更新的时,子组件一定会重新渲染
优化的角度
- 减少组件的不必要渲染
- 提高组件的可读性以及减少复杂度,避免出现难以发现的bug
useMemo
useMemo是一个 React Hook,它在每次重新渲染的时候能够缓存计算的结果。
- 也就是说通过
useMemo后在依赖项不发生变化时,可以不去进行大量非必要的计算,直接得到上次计算的结果
ini
const cachedValue = useMemo(calculateValue, dependencies)
上代码
jsx
const filterTodo = (num: number) => {
console.time("start");
for (let index = 0; index < num; index++) {
const elementNode = document.createElement("div");
}
console.timeEnd("start");
return;
};
const Com2 = React.memo((props: any) => {
console.log("Com2===> 重新渲染了");
const [com2Data, setCom2Data] = useState(10000);
const [data, setData] = useState(0);
const visibleTodos = filterTodo(com2Data);
return (
<>
<span>Com2的数据: {com2Data}</span>
<br />
<br />
<button
onClick={() => {
setCom2Data(com2Data+1);
}}
>
点击Com2数据
</button>
</>
);
});
function App() {
const [appData, setAppData] = useState(0);
console.log("App===> 重新渲染了");
const handleFun = useCallback(() => {
console.log("我是一个函数");
}, []);
return (
<>
<span>Com2的数据: {com2Data}</span>
<br />
<span>Com2的数据data: {data}</span>
<br />
<button
onClick={() => {
setCom2Data(com2Data);
}}
>
点击Com2数据
</button>
<button
onClick={() => {
setCom2Data(com2Data);
}}
>
点击Com2数据
</button>
</>
);
}
export default App;

- 点击下appData按钮
不出意外,这也是我们期待的,因为唯一的props被useCallback包裹
- 点击下Com2按钮

也不出意外,是预料之内的,但是每次渲染都会触发filterTodo这里也没啥太大问题,损耗的时间也不多,但是如果大量计算的时候 ,这里的损耗就要值得关注了,
这时候useMemo就该出场了
jsx
const Com2 = React.memo((props: any) => {
console.log("Com2===> 重新渲染了");
const [com2Data, setCom2Data] = useState(10000);
const [data, setData] = useState(0);
const visibleTodos = useMemo(() =>filterTodo(100000),[com2Data]);
return (
<>
<span>Com2的数据: {com2Data}</span>
<br />
<span>Com2的数据data: {data}</span>
<br />
<button
onClick={() => {
setCom2Data(com2Data);
}}
>
点击Com2Data
</button>
<button
onClick={() => {
setCom2Data(com2Data);
}}
>
点击Com2Data
</button>
</>
);
});