函数组件 hook--useMemo

useMemo

useMemo作用是让一段代码在开始运行一次,后续只有依赖的数据发生变化时才重新运行。类似于vue的计算属性,它会缓存一个数据,让其不会重新创建。它会将传入的函数的返回结果进行缓存,只有当依赖项数组监听的数据发生了变化才会重新计算返回新的结果,否则就取出之前缓存的结果。与Vue不同的是React需要自己配置依赖项。

useMemo产生原因的示例

js 复制代码
import { useState } from 'react'

function App() {
  console.log("App函数体执行了");
  let [arr, setArr] = useState([2, 4, 6, 7]);
  let [msg, setMsg] = useState("I Am Gloria");
  // 数组求和
  let all = arr.reduce((a, b) => a + b, 0);
  // 修改msg
  const change = () => {
    setMsg("I Am Gloria World Tour");
  }
  return (
    <>
      <h1>App</h1>
      <p>{all}</p>
      <p>{msg}</p>
      <button onClick={change}>修改msg</button>
    </>
  )
}

export default App

如上图所示,当我们修改了msg的数据,App整个函数体也重新运行了,此时也重新计算了数组的求和并且又重新创建了all这个变量。这其实就是性能的损耗,因为代码中并没有修改数组的元素,所以对于数组的求和计算并不需要重新运行。此时就可以用useMemo来解决这个问题,将数据缓存,让其不会重新创建。

语法和使用

js 复制代码
// 将需要缓存的数据通过函数return返回
useMemo(函数,数组); // 当数组中的其中一个元素,发生变化时,就会调用函数 。

关于useMemo第二个参数说明,和useEffect第二个参数同理:

  • 不传第二个参数相当于componentDidMountcomponentDidUpdate,在页面初次加载时和页面重新渲染时都会重新执行第一个参数的函数体
  • 第二个参数传空数组相当于componentDidMount,只在页面初次加载时会执行第一个参数的函数体
  • 第二个参数数组中存放某个变量相当于watch监听,在页面初次加载时和修改了监听的数据时会执行第一个参数的函数体
js 复制代码
import { useState, useMemo } from 'react'

function App() {
  console.log("App函数体执行了");
  let [arr, setArr] = useState([2, 4, 6, 7]);
  let [msg, setMsg] = useState("I Am Gloria");
  // 数组求和,创建变量接受useMemo第一个参数函数所返回的结果,返回的数据会被缓存起来
  let all = useMemo(() => {
    console.log("all求和运算被执行");
    return arr.reduce((a, b) => a + b, 0);
  }, [arr]);
  let all1 = useMemo(() => {
    console.log("all1求和运算被执行");
    return arr.reduce((a, b) => a + b, 0);
  }, []);
  let all2 = useMemo(() => {
    console.log("all2求和运算被执行");
    return arr.reduce((a, b) => a + b, 0);
  });
  // 修改msg
  const change = () => {
    setMsg("I Am Gloria World Tour");
  }
  // 修改arr
  const changeArr = () => {
    // useState修改数据会浅比较修改的数据和之前的数据是否相同,所以对于引用数据需要重新修改引用地址
    const _arr = [...arr];
    _arr.push(8);
    setArr(_arr);
  }
  return (
    <>
      <h1>App</h1>
      <p>{all}</p>
      <p>{all1}</p>
      <p>{all2}</p>
      <p>{msg}</p>
      <div>{arr}</div>
      <button onClick={change}>修改msg</button>
      <button onClick={changeArr}>修改arr</button>
    </>
  )
}

export default App

总结

函数组件每次重新渲染时,都会把函数体里的所有代码执行一遍。useMemo解决的是防止函数组件里的不需要被重复执行的代码被多次被执行。比如有一个变量,它的数据并没有修改,而是修改了其他数据,此时函数组件就会重新渲染,整个函数组件的函数体就会重新运行,而这个变量就会被重新创建,useMemo就可以防止一个变量被重复的重新创建。

相关推荐
早點睡3901 小时前
基础入门 React Native 鸿蒙跨平台开发:react-native-flash-message 消息提示三方库适配
react native·react.js·harmonyos
早點睡3902 小时前
高级进阶 ReactNative for Harmony项目鸿蒙化三方库集成实战:react-native-image-picker(打开手机相册)
react native·react.js·harmonyos
早點睡3902 小时前
基础入门 React Native 鸿蒙跨平台开发:react-native-easy-toast三方库适配
react native·react.js·harmonyos
●VON12 小时前
React Native for OpenHarmony:2048 小游戏的开发与跨平台适配实践
javascript·学习·react native·react.js·von
光影少年13 小时前
react状态管理都有哪些及优缺点和应用场景
前端·react.js·前端框架
冻感糕人~14 小时前
【珍藏必备】ReAct框架实战指南:从零开始构建AI智能体,让大模型学会思考与行动
java·前端·人工智能·react.js·大模型·就业·大模型学习
lbb 小魔仙17 小时前
【HarmonyOS实战】React Native 鸿蒙版实战:Calendar 日历组件完全指南
react native·react.js·harmonyos
LYFlied20 小时前
从 Vue 到 React,再到 React Native:资深前端开发者的平滑过渡指南
vue.js·react native·react.js
AAA阿giao1 天前
从零拆解一个 React + TypeScript 的 TodoList:模块化、数据流与工程实践
前端·react.js·ui·typescript·前端框架
摘星编程2 天前
React Native鸿蒙版:Image图片占位符
react native·react.js·harmonyos