React.Component 與 React.PureComponent的區別

前言 先說說 shouldComponentUpdate

提起React.PureComponent,咱們還要從一個生命週期函數 shouldComponentUpdate 提及,從函數名字咱們就能看出來,這個函數是用來控制組件是否應該被更新的。javascript

簡單來講,這個生命週期函數返回一個布爾值,若是返回true,那麼當props或state改變的時候進行更新;若是返回false,當props或state改變的時候不更新,默認返回true。(這裏的更新不更新,其實說的是執不執行render函數,若是不執行render函數,那天然該組件和其子組件都不會從新渲染啦)java

重寫shouldComponentUpdate能夠提高性能,它是在從新渲染過程開始前觸發的。當你明確知道組件不須要更新的時候,在該生命週期內返回false就行啦!react

下面是一個重寫shouldComponentUpdate的例子:數組

class CounterButton extends React.Component { constructor(props) { super(props); this.state = {count: 1}; } shouldComponentUpdate(nextProps, nextState) { if (this.props.color !== nextProps.color) { return true; } if (this.state.count !== nextState.count) { return true; } return false; } render() { return ( <button color={this.props.color} onClick={() => this.setState(state => ({count: state.count + 1}))} > Count: {this.state.count} </button> ); } }

React.Component 與 React.PureComponent

言歸正傳,接下來講咱們今天要討論的React.Component 與 React.PureComponent函數

一般狀況下,咱們會使用ES6的class關鍵字來建立React組件:性能

class MyComponent extends React.Component { // some codes here ... }

可是,你也能夠建立一個繼承React.PureComponent的React組件,就像這樣this

class MyComponent extends React.PureComponent { // some codes here }

那麼,問題來了,這兩種方式有什麼區別呢?spa

    1. 繼承PureComponent時,不能再重寫shouldComponentUpdate,不然會引起警告(報錯截圖就不貼了,怪麻煩的)指針

      Warning: ListOfWords has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.code

    2. 繼承PureComponent時,進行的是淺比較,也就是說,若是是引用類型的數據,只會比較是否是同一個地址,而不會比較具體這個地址存的數據是否徹底一致

      class ListOfWords extends React.PureComponent { render() { return <div>{this.props.words.join(',')}</div>; } } class WordAdder extends React.Component { constructor(props) { super(props); this.state = { words: ['marklar'] }; this.handleClick = this.handleClick.bind(this); } handleClick() { // This section is bad style and causes a bug const words = this.state.words; words.push('marklar'); this.setState({words: words}); } render() { return ( <div> <button onClick={this.handleClick}>click</button> <ListOfWords words={this.state.words} /> </div> ); } }

      上面代碼中,不管你怎麼點擊按鈕,ListOfWords渲染的結果始終沒變化,緣由就是WordAdder的word的引用地址始終是同一個。

    3. 淺比較會忽略屬性或狀態突變的狀況,其實也就是,數據引用指針沒變而數據被改變的時候,也不新渲染組件。但其實很大程度上,咱們是但願從新渲染的。因此,這就須要開發者本身保證避免數據突變。
      若是想使2中的按鈕被點擊後能夠正確渲染ListOfWords,也很簡單,在WordAdderhandleClick內部,將 const words = this.state.words; 改成const words = this.state.words.slice(0); 就行啦~(這時的words是在原來state的基礎上覆製出來一個新數組,因此引用地址固然變啦)

相關文章
相關標籤/搜索