React 第十七节 useMemo用法详解

发布于:2024-12-19 ⋅ 阅读:(10) ⋅ 点赞:(0)

概述

useMemo 是React 中的一个HOOK,用于根据依赖在每次渲染时候缓存计算结果
大白话就是,只有依赖项发生变化时候,才会重新渲染为新计算的值,否则就还是取原来的值,有点类似 vue 中的 computed 计算属性,注意与 useEffect 区分;

写法

const value = useMemo(fnc, [a,b])

第一个参数fnc 是一个函数,用于根据 依赖项 a、b变化时候触发计算得出新值,必须是一个没有任何参数的纯函数,可以返回任意类型;若 a、b没有变化,则React 返回与上次相同的值;若 a、b 发生改变,则会返回新的值;
第二个参数[a、b] 是一个数组,函数 fnc中计算所依赖的值,这个数组中若不传入具体变量,而是传入 空数组[],那么会在组件每次更新时候重新渲染;

这种缓存值的方式叫做 记忆化 (memoization), 这也是这个Hook 称为 useMemo 的由来

使用场景

1、当我们在 useMemo 中的代码运行很慢,通过使用 useMemo 运行效率得到显著提升;
2、将计算结果作为 props 传递给包裹在 memo 中的组件。当计算结果没有改变时,你会想跳过重新渲染。记忆化让组件仅在依赖项不同时才重新渲染。
3、你传递的值稍后用作某些 Hook 的依赖项。例如,也许另一个 useMemo 计算值依赖它,或者 useEffect 依赖这个值。

例如:
将计算结果作为 props 传给子组件

// 父组件
import React, {useMemo, useState} from 'react'
import ChildA from './childA'
export default function MyMemo() {
    const [firstName, setFirstName] = useState('Andy')
    const [lastName, setLastName] = useState('Li')
    const [count, setCount] = useState(0)
    const fullName = useMemo(() => {
        console.log('==useMemo==')
        return firstName +'' + lastName
    }, [firstName, lastName]) // 第二个参数是数组,表示fullName 依赖 firstName 和 lastName 的值,只有 firstName 和 lastName 值发生变化,fullName 才重新计算
    const handleChangeName = (e, type) => {
        console.log('==handleChangeName==', e)
        // [`set${type}`](e.target.value)
        // if (type === 'FirstName') {
        //     setFirstName(e.target.value)
        // } else {
        //     setLastName(e.target.value)
        // }
    }
    const handleChangeFirstName = () => {
        console.log('==更新第一个名称=')
        setCount(count+1)
        setFirstName(11)
    }
  return (
    <div>
      <input type="text"  value={firstName} onChange={(e) => handleChangeName(e, 'FirstName')} />
      <p>点击了{count}</p>
      <button onClick={handleChangeFirstName}>firstName</button>
      <br/>
      <input type="text" value={lastName} onChange={(e) => handleChangeName(e, 'LastName')} />
      <hr />
        <ChildA fullName={fullName}></ChildA>
    </div>
  )
}
// 子组件
import React, {memo, useState} from 'react'
const ChildA = memo(({fullName}) =>{
    console.log('=render=ChildA==fullName----', fullName)
    return (
      <div>
          <p>全称:{fullName}</p>
      </div>
    )
})
export default ChildA

在这里插入图片描述
通过 log日志,我们可以发现,共计点击了 firstName 按钮 18次;只有在初始化第一次点击时候才会渲染 子组件;
因为第一次点击将 firstName 更新为 11;之后的点击传入相同的值 11,导致 useMemo 返回的 fullName 是相同的,故不再进行渲染

而当我们使用 useEffect 时候,会每次都更新子组件

注意:

1、useMemo 只能作为组件代码性能优化使用,如果在不使用 useMemo时,代码无法正常运行,那么我们需要先排查问题,之后再使用 useMemo
2、避免不必要的更新 state 的 Effect;React 中很多的性能是由于其自身的更新链导致的,所以我们要避免重复的更新同一个组件
3、尽可能的减少依赖项,避免过多的依赖导致代码难以理解,难以追踪问题;我们可以将依赖项 设置成 state;
4、我们应该减少状态的提升,多使用state,而不是滥用useMemo来处理性能;


网站公告

今日签到

点亮在社区的每一天
去签到