专业编程基础技术教程

网站首页 > 基础教程 正文

React Hooks - useMemo()使用说明

ccvgpt 2024-08-07 18:54:23 基础教程 11 ℃

useMemo

首先看一下React官方文档的描述

Pass a “create” function and an array of dependencies. useMemo will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render.

React Hooks - useMemo()使用说明

粗略翻译

通过定义一个处理函数和指定一个依赖项的数组。useMemo将保证只有在依赖项中的数据发生变动,才会重新计算处理函数。这将最大程度地避免了在每次渲染组件时都需要重新执行函数计算。

memomemorization的前缀,直译为记住,这里的语境当然是指缓存

    // 只有在a或b变动时,才会执行函数
    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

React 刷新机制

摘自React 官方文档

The setState function is used to update the state. It accepts a new state value and enqueues a re-render of the component.

说明当组件中状态(state)发生改变(严谨地说是setState()调用后), 组件JSX会重新渲染,包括子组件

这样就会发生一些无意义的重复计算,因为通常的状态改变都是局部的,而re-render却是全局的

不使用useMemo

首先看一个反例,这个场景不使用useMemo会发生什么

import React, {useState, useEffect, useMemo} from 'react'

const App = () => {
  
  const [a, setA] = useState(0);
  const [b, setB] = useState(0);
  const [c, setC] = useState(0);

  const aPlusB = () => {
      console.log('又计算了一次')
    return a + b;
  }
    
  return (
    <>
        <h1>合计: {aPlusB()}</h1>
        <h1>a = {a}</h1>
        <h1>b = {b}</h1>
        <h1>c = {c}</h1>

        <button onClick={() => setA(a + 1)}>a + 1</button>
        <button onClick={() => setB(b + 1)}>b + 1</button>
        <button onClick={() => setC(c + 1)}>c + 1</button>
    </>
  );
}

export default App;

页面上

三个按钮依次点击了1次,aPlusB函数也调用了3次,但是根据代码可以看到这个状态c是不参与函数计算的, 他的变动对于aPlusB()的计算结果没有任何影响

从性能角度出发,我们希望只有参与函数计算,对最后结果有影响的状态改变时才应该重新执行函数。useMemo就是干这事的,能避免无意义的执行函数

使用useMemo

import React, {useState, useEffect, useMemo} from 'react'

const App = () => {
  
  const [a, setA] = useState(0);
  const [b, setB] = useState(0);
  const [c, setC] = useState(0);

  // 此时aPlusB已经不是一个函数,而是一个从缓存中取出的值
  const aPlusB = useMemo(() => {
      console.log('又计算了一次')
      return a + b;
  }, [a, b])

  return (
    <>
        <h1>合计: {aPlusB}</h1> // 因为不是函数,因此去掉了括号
        <h1>a = {a}</h1>
        <h1>b = {b}</h1>
        <h1>c = {c}</h1>

        <button onClick={() => setA(a + 1)}>a + 1</button>
        <button onClick={() => setB(b + 1)}>b + 1</button>
        <button onClick={() => setC(c + 1)}>c + 1</button>
    </>
  );
}

export default App;

控制台结果

同样三个按钮依次点击了1次,aPlusB中的逻辑函数只执行了2次,这样就达到了我们想要的效果

Tags:

最近发表
标签列表