熟悉 react 的都知道,react 做效能優化時有乙個避免重複渲染的大招,就是使用 `shouldcomponentupdate()`,但它預設返回 `true`,即始終會執行 `render()` 方法,然後做 virtual dom 比較,並得出是否需要做真實 dom 更新,這裡往往會帶來很多無必要的渲染並成為效能瓶頸。
當然我們也可以在 `shouldcomponentupdate()` 中使用使用 deepcopy 和 deepcompare 來避免無必要的 `render()`,但deepcopy 和 deepcompare 一般都是非常耗效能的。
immutable 則提供了簡潔高效的判斷資料是否變化的方法,只需 `===` 和 `is` 比較就能知道是否需要執行 `render()`,而這個操作幾乎 0 成本,所以可以極大提高效能。修改後的 `shouldcomponentupdate` 是這樣的:
import from 'immutable';
shouldcomponentupdate = (nextprops = {}, nextstate = {}) => , thisstate = this.state || {};
if (object.keys(thisprops).length !== object.keys(nextprops).length ||
object.keys(thisstate).length !== object.keys(nextstate).length)
for (const key in nextprops)
}for (const key in nextstate)
} return false;
}
this.state = )
}this.setstate()
不建議你在state中使用immutablejs。一般用在reducer層。
因為 state 本身必須是 plain object,但是裡面的值可以是 immutable 的資料
當我們需要使用乙個東西的時候,自然是遇到了一些不使用這種東西就難以解決的一些問題。
今天在寫react應用的時候,發現乙個問題,就是在不是用redux的情況下,當container級別的元件的state的結構變得比較複雜的時候,每次修改葉子節點的資料進行setstate的時候就會變得非常麻煩。比如下面這種
class container extends component }};
} ...
}
每次想要修改a.aa.aaa的值,進行setstate就會很麻煩
onchnage() }})
}
每次只更改乙個小點,你就需要將整個state的結構重新寫一遍,現在當然還勉強可行,但是如果當資料結構變成a,b,c,d...都有這種巢狀,難道還是這樣重複寫一次?那估計到了後期,每天寫兩個setstate,我們就可以回家吃飯了。
當然,有的朋友可能一般寫**是這樣寫的。
onchange()
這種做法當然是不可取的,而且當你這麼寫的時候,react會丟擲警告,告訴你不能直接修改state的值。如果你了解過setstate的原理,你就會知道setstate並不會立即更新ui,它是乙個非同步更新流程。每次呼叫setstate的時候,你要更新的state會先被儲存,然後在執行棧的末尾進行合併。如果你直接修改了state,那麼整個state在當前執行棧中就會變得非常混亂,你不會知道state是先在哪個方法中被修改,因此非常容易造成一些無法預知的錯誤。那···我們怎麼解決這個問題呢。
賦值?
var mystate = this.state;
mystate.aa.aaa = 2;
this.setstate(mystate);
可行嗎?當然不行,因為js是引用賦值,這種方式與直接修改state沒有任何差別。所以,沒辦法了,我們只能採用深度轉殖。但是採用深度轉殖,會面臨非常嚴重的效能問題,也不會是我們的最優解決方案。那麼,這個時候就需要用到immutable了,構建不可變資料結構,每次更改當前的資料,都會生成乙個新的資料結構。同時,因為immutable內部採用了特殊的優化方式,只有更改的節點會被轉殖,沒有被更改的節點會被共享,所以依然保持了較低的效能消耗,這樣一來,我們進行狀態的修改,就沒有什麼後顧之憂了。
當然,我前面提到的情況只是immutable展示威力的乙個小場景,如果專案中使用了immutable,會帶來更多意想不到的好處。
這個是比較常用的方法,傳入object,返回map,傳入array,返回list,所以一般的資料轉換用這個就足夠了
import from 'immutable';
let origin =
}}let imt = fromjs(orgin);
使用了immutable後,就不能像之前a.aa.aaa這樣來獲取資料了,我們需要使用get()方法
let aaa = imt.get('a').get('aa').get('aaa');
update的第乙個引數是key,但是第二個引數是乙個函式,其引數是原本的值,這點需要注意
let result = imt.get('a').get('aa').update('aaa', old => 2);
貼一下結合了immutbale寫的乙個簡單的tab元件
import react, from 'react';
import topbar from './top-bar';
import content from './content';
import from 'immutable';
class container extends component ;
this.changefocus = this.changefocus.bind(this);
} changefocus(index)
render()
}export default container;
import react from 'react';
import "./top-bar.css";
let topbar = () =>
export default topbar;
import react, from 'react';
class content extends component
);})
return (
);}}
export default content;
React中為什麼要使用immutableJs
當父元件讀取子元件資料form,賦值給obj,然後對obj進行一些修改過程中,直接賦值就是淺拷貝,修改obj之後會影響form物件,也就會影響子元件中的form的值,這也就是js中的隱患,在react中向上層元件或者下層元件傳遞物件,很難保證這個物件是否會被修改,當不希望對form產生影響的時候,需...
react 使用小結
1 動態獲取object資料,必須給資料乙個初始值,否則無法呼叫,物件裡面的資料,跑出錯誤 2 請求的資料最好在 componentdidmount 中,有動態更新的資料,用state儲存,或者使用 mobx redux 進行資料管理,其他的如 componentdidupdate使用起來非常消耗效...
日期排序react 使用React對錶資料進行排序
通常,當擁有包含資訊的表時,希望能夠按公升序或降序對錶中的資訊進行排序,尤其是在處理數字時。先決條件 在我們繼續之前,讓我們看看我們將在本教程中使用的內容 foundation 用於一般樣式。我們為 樣式使用它,因為我們不希望被本教程中的樣式分散注意力 reactjs 請注意,我不打算在本教程中解釋...