概述
相当于计算属性!!!
useMemo实际的目的也是为了进行性能的优化。
◼ 如何进行性能的优化呢?
useMemo返回的也是一个 memoized(记忆的) 值;
在依赖不变的情况下,多次定义的时候,返回的值是相同的;
在类组件中计算属性实现方式如下:
class App extends React.Component {
get computedName() {
return this.state.name + '计算属性'
}
render() {
return <div></div>
}
}
基本用法
语法:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
- 第一个参数是一个函数,在函数内部需要返回一个结果;该回调函数会被调用,并通过返回值指定需要被记住的数据
- 第二个参数是一个数组(用于指定回调函数中依赖(用到)的数据),即需要监听的属性,一旦监听属性改变后,那么结果就会重新计算,如果没有数组,那么每次组件更新时都会重新计算,比较耗性能,因此在没有依赖项时,建议传入空数组([])
- 返回值:useMemo 记住的数据
- useMemo 记住的数据会一直生效(或者说会一直返回同一个数据),直到依赖项发生改变
useCallback
:只能记忆函数。而 useMemo
可以记忆任何数据
使用场景:类似于 useCallback,可以在组件更新期间保持任意数据引用相等,一般用来处理对象类型的数据useCallback 只能记忆函数,而 useMemo 作用:记忆任意数据,这个被记住的数据会一直生效,直到依赖项发生改变1。
如何选择使用哪一个?
- 如果处理的是函数,推荐使用 useCallback 函数
- 如果处理的是其他数据(比如,对象),推荐使用 useMemo 函数。
示例:
import React from "react";
import { useMemo, useState } from "react";
export default function UseMemo() {
let [firstName, setFirstName] = useState("张");
let [lastName, setLastName] = useState("三");
let fullName = useMemo(() => {
return firstName + lastName;
}, [firstName, lastName]);
return (
<div>
<p> 姓名:{fullName}</p>
</div>
);
}
场景:
- 进行大量的计算操作,是否有必须要每次渲染时都重新计算
- 对子组件传递相同内容的对象时,使用useMemo进行性能的优化
模拟useCallback
useCallback(fn, deps)
相当于 useMemo(() => fn, deps)
。
const help = useCallback(() => {
setCount(count - 1)
}, [count])
// 模拟 useCallback
const help = useMemo(() => {
return () => {
setCount(count - 1)
}
}, [count])
总结
相较于 useCallback 而言,useMemo 的收益是显而易见的。
useMemo 建议适当使用
如果没有使用 useMemo,computeExpensiveValue
会在每一次渲染的时候执行。如果使用了 useMemo
,只有在 a
和b
变化时,才会执行一次 computeExpensiveValue
这笔账大家应该都会算,所以我建议 useMemo 可以使用。
当然也不是无节制的使用,在很简单的基础类型计算时,可能 useMemo 并不划算。