React.js 中的純元件


我們有一個生命週期方法叫做 shouldComponentUpdate,它預設返回 true(布林值)。

shouldComponentUpdate 的目的是我們可以自定義實現預設行為,並決定 React 何時應該更新或重新渲染元件。

通常我們使用 state 或 props 值來決定更新週期。React 現在為我們提供了一個 PureComponent,它會比較 state 和 props 來決定更新週期。如果我們用 PureComponent 擴充套件類,則不需要重寫 shouldComponentUpdate。

React 對當前 state 和 props 與新的 props 和 state 進行淺比較,以決定是否繼續下一個更新週期。

這有助於提高應用程式的效能。但是,只有在比較每個 state 和 props 有意義的情況下,我們才應該用 PureComponent 擴充套件類。否則,如果不需要所有 state 和 props 的比較,我們可以自己實現 shouldComponentUpdate。

這個擴充套件 PureComponent 只適用於基於類的有狀態元件。對於函式式元件,我們可以使用純函式,如下所示:

無狀態元件示例

import { pure } from ‘recompose’;
export default pure ( (props) => {
   //custom code
   return ‘something useful’ ;// your code
})

有狀態元件示例

import React, {PureComponent} from ‘react’;
export default class Test extends PureComponent{
   render(){
      return ‘’;
   }
}

由於 PureComponent 對 state 和 props 物件進行淺比較,因此如果這些物件包含巢狀的資料結構,則 PureComponent 實現的 shouldComponentUpdate 將返回 false。它甚至可能跳過此元件子樹的整體更新。

在這種情況下,子元素也應該是 Pure 的。

因此,巢狀資料結構的比較與 PureComponent 配合得不好。只有當 state 和 props 是簡單物件時,它才有效。

如果元件在任何時候對於相同的輸入值都返回相同的輸出,則可以將其稱為純元件。

如果 state 或 props 引用新的物件,PureComponent 將每次都重新渲染。

應不可變地修改物件,以便使用 PureComponent 成功更新。

如果 shouldComponentUpdate 失敗,我們可以使用 forceUpdate 手動重新渲染。如果我們在淺比較中嵌套了物件,可以使用 immutable.js。

示例

class Test extends React.PureComponent {
   constructor(props) {
      super(props);
      this.state = {
         taskList: [
            { title: 'excercise'},
            { title: 'cooking'},
            { title: 'Reacting'},
         ]
      };
   }
   componentDidMount() {
      setInterval(() => {
         this.setState((oldState) => {
            return { taskList: [...oldState.taskList] }
         });
      }, 1000);
   }
   render() {
      console.log(“taskList render called”);
      return (<div>
         {this.state.taskList.map((task, i) => {
            return (<Task
               key={i}
               title={task.title}
            />);
         })}
      </div>);
   }
}
class Task extends React.Component {
   render() {
      console.log(“task added”);
      return (<div>
         {this.props.title}
      </div>);
   }
}
ReactDOM.render(<Test />, document.getElementById('app'));

我們從 componentDidMount 之後每秒手動觸發一次 prop 更改呼叫,只是為了展示每次如何渲染每個任務。

請檢查瀏覽器控制檯日誌。

因為 Task 元件沒有擴充套件 PureComponent。React不知道發生了什麼變化,所以它每次都會渲染 Task。

所以現在只需用下面的程式碼更改 Task 元件

Export default class task extends PureComponent => 這解決了 Task 的多次渲染問題,並在沒有新增新任務的情況下防止不必要的渲染。

更新於:2019年9月4日

2K+ 瀏覽量

啟動你的職業生涯

完成課程獲得認證

開始學習
廣告
© . All rights reserved.