網站首頁 編程語言 正文
問題背景
大家在使用 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 進行優化
在以上組件的基礎上,給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;
原文鏈接:https://blog.csdn.net/qq_44588612/article/details/127613936
相關推薦
- 2021-12-12 【Groovy】集合遍歷 ( 使用集合的 eachWithIndex 方法進行遍歷 | 代碼示例 )
- 2022-03-18 .NET?6開發TodoList應用之使用MediatR實現POST請求_實用技巧
- 2022-07-14 Android實現ViewFlipper圖片動畫滑動_Android
- 2023-10-24 記ElementUI內置的$confirm確認消息彈框方法
- 2023-08-13 Spring Security 構建基于 JWT 的登錄認證
- 2022-05-20 Windows10或者11 使用Administrator登錄
- 2022-09-05 C語言中scanf函數的原樣輸入的坑及解決_C 語言
- 2022-08-25 詳解C語言中結構體的使用_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支