React Native之組件Component與PureComponent
眾所周知,React Native的頁面元素是由一個一個的組件所構成的,這些組件包括系統(tǒng)已經(jīng)提供的組件,如View、TextInput等,還有一些第三方庫提供的組件,以及自定義的組件。通常在封裝組件的時候都會繼承Component,不過在React 15.3版本中系統(tǒng)提供了PureComponent,下面就來看一下這兩個組件的區(qū)別。
首先聲明,PureComponent是Component的一個優(yōu)化組件,在React中的渲染性能有了大的提升,可以減少不必要的 render操作的次數(shù),從而提高性能。PureComponent 與Component 的生命周期幾乎完全相同,但 PureComponent 通過prop和state的淺對比可以有效的減少shouldComponentUpate()被調(diào)用的次數(shù)。
PureComponent VS Component 原理
當組件更新時,如果組件的props和state都沒發(fā)生改變,render方法就不會觸發(fā),省去 Virtual DOM 的生成和比對過程,達到提升性能的目的。原理就是 React會自動幫我們做了一層淺比較,涉及的函數(shù)如下:
if?(this._compositeType?===?CompositeTypes.PureClass)?{ shouldUpdate?=?!shallowEqual(prevProps,?nextProps) ||?!shallowEqual(inst.state,?nextState); }
PureComponent 的shouldComponentUpdate() 只會對對象進行淺對比,如果對象包含復雜的數(shù)據(jù)結構,它可能會因深層的數(shù)據(jù)不一致而產(chǎn)生錯誤的否定判斷。所以,在實際使用的時候,當你期望只擁有簡單的props和state時,才去繼承PureComponent ,或者在你知道深層的數(shù)據(jù)結構已經(jīng)發(fā)生改變時使用forceUpate() 。
Component
首先要看Component的生命周期示意圖。
下面就Component的生命周期
生命周期
執(zhí)行過一次后,被創(chuàng)建的類會有緩存,映射的值會存在this.props,前提是這個prop不是父組件指定的。這個方法在對象被創(chuàng)建之前執(zhí)行,因此不能在方法內(nèi)調(diào)用this.props ,另外,注意任何getDefaultProps()返回的對象在實例中 共享,而不是復制。
控件加載之前執(zhí)行,返回值會被用于state的初始化值。
執(zhí)行一次,在初始化render之前執(zhí)行,如果在這個方法內(nèi)調(diào)用setState,render()知道state發(fā)生變化,并且只執(zhí)行一次。
調(diào)用render()方法時,首先檢查this.props和this.state返回一個子元素,子元素可以是DOM組件或者其他自定義復合控件的虛擬實現(xiàn) 。
如果不想渲染可以返回null或者false,這種場景下,React渲染一個
在初始化render之后執(zhí)行,且只執(zhí)行一次,在這個方法內(nèi),可以訪問任何組件,componentDidMount()方法中的子組件需要在父組件之前執(zhí)行。
這個方法在初始化render()時不會執(zhí)行,當props或者state發(fā)生變化時執(zhí)行,并且是在render之前執(zhí)行,當新的props或者state不需要更新組件時,返回false。
shouldComponentUpdate:?function(nextProps,?nextState)?{ ??return?nextProps.id?!==?this.props.id; }
當shouldComponentUpdate()返回false時,render()方法將不會執(zhí)行,componentWillUpdate()和componentDidUpdate()也不會被調(diào)用。
默認情況下,shouldComponentUpdate方法返回true,防止state快速變化時的問題,但是如果state不變,props只讀,可以直接覆蓋shouldComponentUpdate用于比較props和state的變化,決定UI是否更新,當組件比較多時,使用這個方法能有效提高應用性能。
當props和state發(fā)生變化時執(zhí)行,執(zhí)行該函數(shù),并且在render方法之前執(zhí)行,緊接著這個函數(shù)就會調(diào)用render()來更新界面。
組件更新結束之后執(zhí)行,在初始化render時不執(zhí)行。
void?componentDidUpdate(??object?prevProps,?object?prevState )
當props發(fā)生變化時執(zhí)行,初始化render時不執(zhí)行,在這個回調(diào)函數(shù)里面,你可以根據(jù)屬性的變化,通過調(diào)用this.setState()來更新你的組件狀態(tài),舊的屬性還是可以通過this.props來獲取,這里調(diào)用更新狀態(tài)是安全的,并不會觸發(fā)額外的render調(diào)用。
componentWillReceiveProps:?function(nextProps)?{ ??this.setState({ ????likesIncreasing:?nextProps.likeCount?>?this.props.likeCount ??}); }
當組件要被從界面上移除的時候,就會調(diào)用componentWillUnmount(),在這個函數(shù)中,可以做一些組件相關的清理工作,例如取消計時器、網(wǎng)絡請求等。
PureComponent
上面為大家講了Component的生命周期,仔細閱讀可以發(fā)現(xiàn),在React 的Component的生命周期中,有一個shouldComponentUpdate方法,該方法默認返回值是true。Component的shouldComponentUpdate函數(shù)源碼如下:
shouldComponentUpdate(nextProps,?nextState)?{??return?true; }
也就是說,不管有沒有改變組件的props或者state屬性,都需要調(diào)用shouldComponentUpdate()來重繪界面,這極大的降低了React的渲染效率。因此,從React在15.3版本中發(fā)布了一個優(yōu)化的PureComponent組件來優(yōu)化React的渲染效率。而PureComponent的shouldComponentUpdate是這樣的。
if?(this._compositeType?===?CompositeTypes.PureClass)?{ ??shouldUpdate?=?!shallowEqual(prevProps,?nextProps)?||?!?shallowEqual(inst.state,?nextState); }
PureComponent使用淺比較判斷組件是否需要重繪,因此,下面對數(shù)據(jù)的修改并不會導致重繪:
options.push(new?Option()) options.splice(0,?1) options[i].name?=?"Hello"
這些例子都是在原對象上進行修改,由于淺比較是比較指針的異同,所以會認為不需要進行重繪。
為了避免出現(xiàn)這些問題,推薦使用immutable.js。immutable.js會在每次對原對象進行添加,刪除,修改使返回新的對象實例,任何對數(shù)據(jù)的修改都會導致數(shù)據(jù)指針的變化。
實例
下面,我們通過一個實例來比較下PureComponent和Component在頁面渲染上面的效率。
import?React,?{?PureComponent,Component?}?from?'react'; import?{ ??AppRegistry, ??StyleSheet, ??Text, ??View, ??Button }?from?'react-native'; export?default?class?test?extends?PureComponent?{ ??constructor(props){????super(props);????this.state?=?{ ???????number?:?1, ???????numbers:?[], ????}; ??} ??render()?{????return?( ??????
如何讓PureComponent重繪
當然,有時候如果繼承PureComponent后需要在變化的時候重繪界面,我們要怎么做?
重寫shouldUpdateComponent方法;
props或者state增減參數(shù);
關于Component與PureComponent的內(nèi)容就為大家介紹到這里,一句話:PureComponent是Component的一個優(yōu)化組件,通過減少不必要的 render操作的次數(shù),從而提高界面的渲染性能。
本文轉(zhuǎn)載自異步社區(qū)
軟件開發(fā) 前端開發(fā)
版權聲明:本文內(nèi)容由網(wǎng)絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權內(nèi)容。