日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

react如何通过shouldComponentUpdate来减少重复渲染

發布時間:2025/3/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 react如何通过shouldComponentUpdate来减少重复渲染 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在react開發中,經常會遇到組件重復渲染的問題,父組件一個state的變化,就會導致以該組件的所有子組件都重寫render,盡管絕大多數子組件的props沒有變化

render什么時候會觸發

首先,先上一張react生命周期圖:

這張圖將react的生命周期分為了三個階段:生成期、存在期、銷毀期,這樣在create、props、state、unMount狀態變化時我們可以清楚的看到reacte觸發了哪些生命周期鉤子以及什么時候會render。

如果我們需要更改root的一個state,使綠色組件視圖更改

如果你寫過vue,你會發現組件更新是如上圖那樣的(視圖指令已編譯為修改視圖的函數存放在綁定的state里的屬性里,所以能夠做到靶向修改),而react會以組件為根,重新渲染整個組件子樹,如下圖(綠色是期望的render路徑,橙色是無用render):

所以在react里,我們探討的render性能優化是react調用render的路徑如下:

如何避免這些不必要的render:

shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState)

使用shouldComponentUpdate()以讓React知道當前狀態或屬性的改變是否不影響組件的輸出,默認返回ture,返回false時不會重寫render,而且該方法并不會在初始化渲染或當使用forceUpdate()時被調用,我們要做的只是這樣:

shouldComponentUpdate(nextProps, nextState) {return nextState.someData !== this.state.someData }

但是,state里的數據這么多,還有對象,還有復雜類型數據,react的理念就是拆分拆分再拆分,這么多子組件,我要每個組件都去自己一個一個對比嗎??不存在的,這么麻煩,要知道我們的終極目標是不勞而獲-_-

React.PureComponent

React.PureComponent 與 React.Component 幾乎完全相同,但 React.PureComponent 通過props和state的淺對比來實現 shouldComponentUpate()。如果對象包含復雜的數據結構,它可能會因深層的數據不一致而產生錯誤的否定判斷(表現為對象深層的數據已改變視圖卻沒有更新)

關注點:
  • 無論組件是否是 PureComponent,如果定義了 shouldComponentUpdate(),那么會調用它并以它的執行結果來判斷是否 update。在組件未定義 shouldComponentUpdate() 的情況下,會判斷該組件是否是 PureComponent,如果是的話,會對新舊 props、state 進行 shallowEqual 比較,一旦新舊不一致,會觸發 update。
  • 淺判等 只會比較到兩個對象的 ownProperty 是否符合?Object.js()?判等,不會遞歸地去深層比較---源碼
const hasOwnProperty = Object.prototype.hasOwnProperty;/*** inlined Object.is polyfill to avoid requiring consumers ship their own* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is*/ function is(x: mixed, y: mixed): boolean {// SameValue algorithmif (x === y) { // Steps 1-5, 7-10// Steps 6.b-6.e: +0 != -0// Added the nonzero y check to make Flow happy, but it is redundantreturn x !== 0 || y !== 0 || 1 / x === 1 / y;} else {// Step 6.a: NaN == NaNreturn x !== x && y !== y;} }/*** Performs equality by iterating through keys on an object and returning false* when any key has values which are not strictly equal between the arguments.* Returns true when the values of all keys are strictly equal.*/ function shallowEqual(objA: mixed, objB: mixed): boolean {if (is(objA, objB)) {return true;}if (typeof objA !== 'object' || objA === null ||typeof objB !== 'object' || objB === null) {return false;}const keysA = Object.keys(objA);const keysB = Object.keys(objB);if (keysA.length !== keysB.length) {return false;}// Test for A's keys different from B.for (let i = 0; i < keysA.length; i++) {if (!hasOwnProperty.call(objB, keysA[i]) ||!is(objA[keysA[i]], objB[keysA[i]])) {return false;}}return true; }
  • 至于復雜數據結構,用Object.key()獲取下key,然后key和對應的value都是基礎類型數據,就是算是簡單數據結構,不然就是復雜

針對以上規則我們在項目開發種可以做出如下優化:

盡量將復雜類型數據(ArrayList)所關聯的視圖單獨拆成PureComonent有助于提高渲染性能,比如表單、文本域和復雜列表在同一個 render() 中,表單域的輸入字段改變會頻繁地觸發 setState() 從而導致 組件 重新 render()。而用于渲染復雜列表的數據其實并沒有變化,但由于重新觸發 render(),列表還是會重新渲染。

react-immutable-render-mixin

我想復雜數組沒變化時也不要render(), 那你用react-immutable-render-mixin,來,我們看看插件的介紹:

Users are urged to use PureRenderMixin with facebook/immutable-js. If performance is still an issue an examination of your usage of Immutable.js should be your first path towards a solution. This library was created from experimentations with Immutable that were ultimately erroneous; improper usage of Immutable.js ?. Users should be able to achieve maximum performance simply using PureRenderMixin.


譯:不能以正確的姿勢來使用immutable-js做優化,你就不要瞎折騰了,用它react-immutable-render-mixin就行了

它和ProComponent原理一樣,唯一的區別就是新舊數據的對比,react-immutable-render-mixin用了immutable-js?的is()方法去做對比,性能強,復雜類型數據也能對比(這里不對immutable-js做討論,一篇很不錯的文章Immutable 詳解及 React 中實踐),相比于React.PureComponent更方便---源碼

import Immutable from 'immutable';const is = Immutable.is.bind(Immutable);export default function shallowEqualImmutable(objA, objB) {if (objA === objB || is(objA, objB)) {return true;}if (typeof objA !== 'object' || objA === null ||typeof objB !== 'object' || objB === null) {return false;}const keysA = Object.keys(objA);const keysB = Object.keys(objB);if (keysA.length !== keysB.length) {return false;}// Test for A's keys different from B.const bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);for (let i = 0; i < keysA.length; i++) {if (!bHasOwnProperty(keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {return false;}}return true; }

用法很多,我喜歡Decorator:

import React from 'react'; import { immutableRenderDecorator } from 'react-immutable-render-mixin';@immutableRenderDecorator class Test extends React.Component {render() {return <div></div>;} }

總結

以上是生活随笔為你收集整理的react如何通过shouldComponentUpdate来减少重复渲染的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。