React.memo和useMemo如何正确使用以避免性能问题?

2026-04-02 08:451阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1157个文字,预计阅读时间需要5分钟。

React.memo和useMemo如何正确使用以避免性能问题?

目录 + 问题背景 + useMemo + 进行优化 + React.memo + 进行优化 + props的值是基本类型 + props的值是引用类型 + 写在最后 + 问题背景 + 大家在使用React框架进行开发时,一定会遇到过以下问题:+ 当函数式组件中的函数返回值发生变化时,组件会进行不必要的重新渲染;+ 当组件接收到相同的props时,组件也会进行不必要的重新渲染;+ 当props是基本类型时,即使其值没有变化,组件也会重新渲染;+ 当props是引用类型时,即使其引用的对象没有变化,组件也会重新渲染。

目录
  • 问题背景
  • useMemo 进行优化
  • React.memo 进行优化
    • props的值是基本类型
    • props的值是引用类型
  • 写在最后

    问题背景

    大家在使用 React 框架进行开发时一定遇到过以下问题:

    • 当函数式组件中的某一状态改变,整个组件刷新,重新渲染
    • 在类组件中 setState() 时,整个组件也会重新渲染
    • 以上问题若不进行优化,导致的结果是:
    • 随着代码的增加,每次的状态改变,页面进行一次 reRender ,这将产生很多不必要的 reRender 不仅浪费性能,从而导致页面卡顿;

    useMemo 进行优化

    以下面 App 组件进行分析

    import './App.css'; import ProfileTest from './components'; import { Profiler, useEffect, useMemo, useState, useRef } from 'react' function App () { const [name, setName] = useState('') const [num, setNum] = useState(0) useEffect(() => { setTimeout(() => { console.log('111') setName('xxx') }, 2000) }, []) const memoVal = useMemo(() => { console.log('运行了useMemo num值为:', num); return num + 1 }, [num]) console.log('memoVal值为:', memoVal) console.log('父组件运行分割线----------------------------------------------------') const changeNum = () => { setNum(2) } return ( <Profiler id='profile-test'> <div className="App"> {/* <ProfileTest /> */} <button style={{ marginTop: 100 }} onClick={changeNum}>改变num</button> </div> </Profiler> ); } export default App;

    以上组件在首次渲染、以及 2秒后的执行结构如下图所示:

    很显然首次渲染执行了,useMemo,而2秒后有状态变化后没有执行useMemo。
    点击按钮改变 useMemo 的依赖项后可以发现,如下图所示 useMemo 又执行了。

    因此在使用函数式组件时,可以使用 useMemo 减少不必要的reRender 提高组件的性能;

    React.memo和useMemo如何正确使用以避免性能问题?

    React.memo 进行优化

    在以上组件的基础上,给App 增加一个子组件,代码如下所示:

    import React from 'react' export default function Children(props) { console.log('子组件运行了,接收的props是', props) console.log('子组件渲染分割线------------------------------------------') return <div>子组件</div> }

    首次render 以及 2s后组件的 reRender 控制台打印结果如下图所示:

    由上图可以看出,reRender 时Children 组件的props并未变化,因此,此次Children 组件的reRender 是不必要的,需要进行优化;

    props的值是基本类型

    如果 Children 的 props 是基本类型,则可以做一下优化:

    import React, { memo } from 'react' function Children(props) { console.log('子组件运行了,接收的props是', props) console.log('子组件渲染分割线------------------------------------------') return <div>子组件</div> } export default memo(Children)

    优化后控制台打印如下信息,一下信息可以看出 Children 组件没有进行 reRender

    props的值是引用类型

    若子组件的 props 是引用类型 ,则需要进行深度比较,此时React.memo()要传入第二个参数进行深度比较,改变后 Children 组件的代码如下所示:

    import React, { memo } from 'react' function Children(props) { console.log('子组件运行了,接收的props是', props) console.log('子组件渲染分割线------------------------------------------') return <div>子组件</div> } export default memo(Children, (preProps, nextProps) => { return JSON.stringify(preProps) === JSON.stringify(nextProps) })

    以上 memo 第二个参数 ,通过比较 preProps 和 nextProps 返回一个布尔值,使得props 进行深度比较;
    注意:React.memo的第二个参数进行深度比较时有一定开销,其产生的开销存在大于子组件reRender的可能

    写在最后

    useMemo() 和 React.memo() 都是进行组件性能优化的方式,其区别是

    • useMemo 可以进行更加细粒度的优化(有依赖项)
    • React.memo() 可以控制props的浅比较和深度比较
    • React.memo在没有第二个参数的时候相当于class中的PureComponent,当增加了第二个参数的时候相当于生命周期中的shouldComponentUpdate;

    到此这篇关于React.memo 和 useMemo 的使用问题小结的文章就介绍到这了,更多相关React.memo 和 useMemo内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

    本文共计1157个文字,预计阅读时间需要5分钟。

    React.memo和useMemo如何正确使用以避免性能问题?

    目录 + 问题背景 + useMemo + 进行优化 + React.memo + 进行优化 + props的值是基本类型 + props的值是引用类型 + 写在最后 + 问题背景 + 大家在使用React框架进行开发时,一定会遇到过以下问题:+ 当函数式组件中的函数返回值发生变化时,组件会进行不必要的重新渲染;+ 当组件接收到相同的props时,组件也会进行不必要的重新渲染;+ 当props是基本类型时,即使其值没有变化,组件也会重新渲染;+ 当props是引用类型时,即使其引用的对象没有变化,组件也会重新渲染。

    目录
    • 问题背景
    • useMemo 进行优化
    • React.memo 进行优化
      • props的值是基本类型
      • props的值是引用类型
    • 写在最后

      问题背景

      大家在使用 React 框架进行开发时一定遇到过以下问题:

      • 当函数式组件中的某一状态改变,整个组件刷新,重新渲染
      • 在类组件中 setState() 时,整个组件也会重新渲染
      • 以上问题若不进行优化,导致的结果是:
      • 随着代码的增加,每次的状态改变,页面进行一次 reRender ,这将产生很多不必要的 reRender 不仅浪费性能,从而导致页面卡顿;

      useMemo 进行优化

      以下面 App 组件进行分析

      import './App.css'; import ProfileTest from './components'; import { Profiler, useEffect, useMemo, useState, useRef } from 'react' function App () { const [name, setName] = useState('') const [num, setNum] = useState(0) useEffect(() => { setTimeout(() => { console.log('111') setName('xxx') }, 2000) }, []) const memoVal = useMemo(() => { console.log('运行了useMemo num值为:', num); return num + 1 }, [num]) console.log('memoVal值为:', memoVal) console.log('父组件运行分割线----------------------------------------------------') const changeNum = () => { setNum(2) } return ( <Profiler id='profile-test'> <div className="App"> {/* <ProfileTest /> */} <button style={{ marginTop: 100 }} onClick={changeNum}>改变num</button> </div> </Profiler> ); } export default App;

      以上组件在首次渲染、以及 2秒后的执行结构如下图所示:

      很显然首次渲染执行了,useMemo,而2秒后有状态变化后没有执行useMemo。
      点击按钮改变 useMemo 的依赖项后可以发现,如下图所示 useMemo 又执行了。

      因此在使用函数式组件时,可以使用 useMemo 减少不必要的reRender 提高组件的性能;

      React.memo和useMemo如何正确使用以避免性能问题?

      React.memo 进行优化

      在以上组件的基础上,给App 增加一个子组件,代码如下所示:

      import React from 'react' export default function Children(props) { console.log('子组件运行了,接收的props是', props) console.log('子组件渲染分割线------------------------------------------') return <div>子组件</div> }

      首次render 以及 2s后组件的 reRender 控制台打印结果如下图所示:

      由上图可以看出,reRender 时Children 组件的props并未变化,因此,此次Children 组件的reRender 是不必要的,需要进行优化;

      props的值是基本类型

      如果 Children 的 props 是基本类型,则可以做一下优化:

      import React, { memo } from 'react' function Children(props) { console.log('子组件运行了,接收的props是', props) console.log('子组件渲染分割线------------------------------------------') return <div>子组件</div> } export default memo(Children)

      优化后控制台打印如下信息,一下信息可以看出 Children 组件没有进行 reRender

      props的值是引用类型

      若子组件的 props 是引用类型 ,则需要进行深度比较,此时React.memo()要传入第二个参数进行深度比较,改变后 Children 组件的代码如下所示:

      import React, { memo } from 'react' function Children(props) { console.log('子组件运行了,接收的props是', props) console.log('子组件渲染分割线------------------------------------------') return <div>子组件</div> } export default memo(Children, (preProps, nextProps) => { return JSON.stringify(preProps) === JSON.stringify(nextProps) })

      以上 memo 第二个参数 ,通过比较 preProps 和 nextProps 返回一个布尔值,使得props 进行深度比较;
      注意:React.memo的第二个参数进行深度比较时有一定开销,其产生的开销存在大于子组件reRender的可能

      写在最后

      useMemo() 和 React.memo() 都是进行组件性能优化的方式,其区别是

      • useMemo 可以进行更加细粒度的优化(有依赖项)
      • React.memo() 可以控制props的浅比较和深度比较
      • React.memo在没有第二个参数的时候相当于class中的PureComponent,当增加了第二个参数的时候相当于生命周期中的shouldComponentUpdate;

      到此这篇关于React.memo 和 useMemo 的使用问题小结的文章就介绍到这了,更多相关React.memo 和 useMemo内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!