实现数据缓存 类似vue内的计算属性 useMemo 是一个React Hook,它可以让你在重新渲染之间缓存计算结果。
概念
const cachedValue = useMemo(calculateValue, dependencies)
参数: calculateValue 计算要缓存的值的函数。它应该是纯的,不应该接受任何参数,并且应该返回任何类型的值。
dependencies
在calculateValue代码中引用的所有响应值的列表。响应式值包括props、state以及所有直接在组件内部声明的变量和函数。React将使用Object.is将每个依赖项与之前的值进行比较,写法 [dep1, dep2, dep3]
使用条件
useMemo使用的原因是:在组件内部存在计算属性相关内容时,只渲染需要修改的内容,而下面的内容是,只要有一个属性修改,组件内部的全部内容都会修改
函数组件的每一次更新,都是把函数重新执行一遍
- 函数组件每次运行都会产生一个新的闭包
- 内部代码也要重新执行一遍
如果组件内有一部分内容,只是想其在改变的时候执行这部分代码逻辑,没有改变的时候不执行
import { useMemo } from 'react';
function TodoList({ todos, tab }) {
const visibleTodos = useMemo(
() => filterTodos(todos, tab),
[todos, tab]
);
// ...
}
当 todos, tab 两个值更新的时候,这段代码执行
例子:
import React, { useState, useMemo } from "react";
import { Button } from 'antd';
const Demo = function Demo() {
let [supNum, setSupNum] = useState(10),
[oppNum, setOppNum] = useState(5),
[x, setX] = useState(0);
let ratio = useMemo(() => {
let total = supNum + oppNum,
ratio = '--';
if (total > 0) ratio = (supNum / total * 100).toFixed(2) + '%';
return ratio;
}, [supNum, oppNum]);
return <div className="vote-box">
<div className="main">
<p>支持人数:{supNum}人</p>
<p>反对人数:{oppNum}人</p>
<p>支持比率:{ratio}</p>
<p>x:{x}</p>
</div>
<div className="footer">
<Button type="primary" onClick={() => setSupNum(supNum + 1)}>支持</Button>
<Button type="primary" danger onClick={() => setOppNum(oppNum + 1)}>反对</Button>
<Button onClick={() => setX(x + 1)}>干点别的事</Button>
</div>
</div>;
};
export default Demo;
主要部分:
let ratio = useMemo(() => {
let total = supNum + oppNum,
ratio = '--';
if (total > 0) ratio = (supNum / total * 100).toFixed(2) + '%';
return ratio;
}, [supNum, oppNum]);
let xxx = useMemo(callback,[dependencies])
- 第一次渲染组件的时候,callback会执行
- 后期只有依赖的状态值发生改变,callback才会再执行
- 每一次会把callback执行的返回结果赋值给xxx
- useMemo具备“计算缓存”,在依赖的状态值没有发生改变,callback没有触发执行的时候,xxx获取的是上一次计算出来的结果
useMemo是一个优化的Hook函数
使用:如果函数组件中,有消耗性能/时间的计算操作,则尽可能使用useMemo缓存起来,设置相关依赖
优点:如果依赖没有发生改变,消耗性能的计算就不会执行,只有依赖状态发生改变才会执行
这样可以保证,当非依赖的状态发生改变,不会去处理一些没必要的操作,提高组件更新速度。
React.memo(函数组件)
作用于函数组件本身,针对于函数组件新老传递过来的属性做校验,如果传递过来的属性和之前的属性是一致的,值没发生变化时,React.memo是不会让组件更新的
类似于类组件的React.PureComponent
useMemo 不是对整个组件本身做校验的,而是对组件内的某一段处理逻辑做计算缓存的优化类似于vue的computed