Reactjs性能優化(下)

React 實現pure render的時候,bind(this)導致re-render?

先上代碼:

export default class  extends Component {
...
render() {
const {name,age} =this.state;
return (
  <div>
    <Person name={name} age={age} onClick={this._handleClick.bind(this)}></Person>//bug 所在
  </div>
)
}...}

發現一個問題,對於Person這個子組件來說,在父組件re-render的時候,即使Person得前後兩個props都沒改變,它依舊會re-render。。即使用immutable.js也不好使。。。 
原來啊,父組件每次render,_handleClick都會執行bind(this) 這樣_handleClick的引用每次都會改。。所以Person前後兩次props其實是不一樣的。。 
那怎麼辦?把bind(this)去掉?不行 還必須得用 
真正的答案是 讓父組件每次render 不執行bind(this),直接提前在constructor執行好,修改之後

constructor(props){
super(props)
this._handleClick= this._handleClick.bind(this)}
<Person name={name} age={age} onClick={this._handleClick}></Person>

爲了儘可能減少re-render,props中儘可能的使用基本類型,且函數都在constructor中執行好??

如何解決?

避免將函數作爲props傳遞,使用EventEmitter來對父子組件的依賴解耦。

EventEmitter是什麼?

簡單來說,使用EventEmitter,你可以監聽一個事件,並且可以執行一個你綁定的回調函數。就像前端的javascript一樣,你可以通過addEventListener來綁定用戶的鼠標鍵盤交互事件,EventEmitter是基於發佈訂閱模式,因此我們可以通過訂閱事件然後再發布。我們可以看到很多前端javascript庫是支持訂閱發佈模式(angularjs,vuejs),但Node.js是內建的。

有一個重要的問題:你爲什麼要使用事件模式?因爲在Node.js裏,他可以替代各種深層嵌套的加調。Node.js很多方法是要異步運行的,這意味着當這個方法完成時,你就要傳遞一個可回調的函數。最後,你會發現你的代碼看起來像一個巨大的漏斗。爲了防止這種情況出現,你可以使用監聽事件來優化這些事件,這可以更好地組織你的代碼,而不是使用回調嵌套的方式。

使用事件方式還有一個好處,就是可以使你的代碼得到很好的解耦。一個事件發出後,如果沒有被監聽,那麼他也不會報錯。

基本使用姿勢 EventEmitter

var events = require("events");
var EventEmitter = require("events").EventEmitter;
var ee = new EventEmitter();
 ee.on("someEvent", function () {
 console.log("event has occured");
});
ee.emit("someEvent");

首先我們創建一個新的EventEmitter對象。這個對象有兩種主要方法: on 和 emit; on這個方法有兩個參數,第一個參數是我們要監聽事件的名稱,在上面的例子,要監聽事件的名稱就是"someEvent"。當然你可以定一個更好的名字。第二個參數是在事件發生時,要執行的函數。

現在要觸發事件,你可以通過事件名稱EventEmitter的實例emit方法。就是上面代碼的最後一行。如果你運行代碼,將得到打印到控制檯的文本。

這是最基本的 EventEmitter 使用,你也可以觸發事件時傳遞一個對象 
傳送門:node的事件模塊應用

小結

爲了避免不必要的re-render,請不要將函數傳入props中,取而代之使用EventEmitter。

儘量遵循此原則,props始終傳遞基本類型或者只包含基本類型的對象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章