ReactJS修煉之路(五):Immutable.js的使用及setState的一個誤區

問題

這篇博客僅作爲學習筆記,沒有多少自己的東西,只有一個小誤區,記錄下來當做備忘。

學習資料:

關於Immutable.js如何整合進React中,推薦閱讀官方的文檔和上面第二篇博客,下面不會說具體的使用方法,所以閱讀到這裏這篇博客算是結束了。

下面說說我以前在setState中踩的坑,同時也回答了一個問題,爲什麼需要Immutable.js這個輪子。

年少時不小心犯下的錯

最近會啓動一個新的項目,在進行技術選型的時候特地看了Immutable.js,才發現自己以前寫碼有些錯誤的地方。

上代碼:

    let data = this.state.data;
    data.times = data.times + 1;
    this.setState({ data: data });
    // 下面打印的結果會是已經加 1 後的值。
    console.log(this.state.data.times);

還記得該系列的上一篇文章ReactJS修煉之路(四):組件的性能優化及開發思路中提到的shouldComponentUpdate: function(nextProps, nextState),因爲上面的操作直接改變了this.state.data的值,所以在shouldComponentUpdatenextState.datathis.state.data其實是同一個對象(2016-12-03更新:這裏容易產生誤區,再說得詳細一點,因爲我們在調用this.setState({ data: data })時,把原來的state中的state賦給了新的state,所以下面的nextState.datathis.state.data是同一個對象,既然是同一個對象的兩個不同引用而已,那麼無論怎麼比較得出的結果都是nextState.datathis.state.data相同,所以返回false),因此無論怎麼比較都會返回false,導致組件不更新。

正確的做法應該如下:

    let data = _.cloneDeep(this.state.data);
    data.times = data.times + 1;
    this.setState({ data: data });
    // 如果上面不做 cloneDeep,下面打印的結果會是已經加 1 後的值。
    console.log(this.state.data.times);

這樣的話,沒有改變this.state.data的值,通過調用setState,使得在shouldComponentUpdatenextState.data是新的值,可以與this.state.data比較,根據比較結果判斷是否更新組件。

那麼爲什麼需要Immutable.js

let data = _.cloneDeep(this.state.data);這行代碼可以看出,爲了新建一個對象,我們在原對象的基礎上進行了深度拷貝,然後改變新對象的值,深度拷貝的壞處很明顯,對象越複雜,性能開銷越大,而Immutable.js能通過不可變對象來避免這個問題,具體原理看上面的學習資料可以求解:

else

有一段時間沒更新博客了,跟國慶假期有關,但主要原因還是遇到的問題少了,倒不是說自己水平提升了很多,而是自己實際編碼的時間少了(話說最近看了《易中天中華史》,十分推薦)。

只有coding能產生問題,也只有coding能解決問題,提升自己。

加油。

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