Immutable.js

Immutable.js在react + router + redux項目中的應(yīng)用

先介紹一下Immutable:

Immutable.js的出現(xiàn)源于Functional Programming的思想,即所有數(shù)據(jù)應(yīng)該是復(fù)制過來,而不是直接修改。相關(guān)介紹看它官網(wǎng):
https://facebook.github.io/immutable-js/

所以如果你有一些編程經(jīng)驗,可以理解為Immutable就是另外一個數(shù)據(jù)結(jié)構(gòu)的庫。就好像從ArrayList換成LinkedList一樣。在Immutable.js下,就是從JavaScript語法自有的Array(就是[])和Object{ }),換到Immutable.ListImmutable.Map了。

但是ArrayListLinkedList畢竟都繼承于List,接口上比較一致,換起來問題不大,但是想用Immutable換JavaScript原生,就要略復(fù)雜些。

var map1 = Immutable.Map({a:1, b:2, c:3});
var map2 = map1.set('b', 50);
map1.get('b'); // 2
/* ----------------悠長悠長的分割線---------------- */
var list1 = Immutable.List.of(1, 2);
var list2 = list1.push(3, 4, 5);
var list3 = list2.unshift(0);
var list4 = list1.concat(list2, list3);

復(fù)雜歸復(fù)雜,不過是多注意一點吧。

然后要說到redux和router

Redux有一個combineReducers方法,可以做到Reducer的拆分。比如:

combineReducers({
  user: userReducer,
  dashboard: dashboardReducer,
})

那么問題來了:
當(dāng)你獲取state的時候,你是用state.get('user')還是用state.user?

顯然要用state.user。因為combineReducers不認(rèn)識Immutable啊。
(不要告訴我混用,一層結(jié)構(gòu)可以這樣,多層呢?多人合作呢?一處蒙逼,處處報錯?。?/p>

所以如果你想在一個react + router + redux的項目下用Immutable,要么就局部使用(局部的話,基本會很nightmare吧),要么就換全套的。
然后就是看這里(這哥們把combineReducers給重新寫了):
https://github.com/gajus/redux-immutable

用他們家的combineReducers,你就可以放心地用state.get('user')。

在解決combineReducers的同時,他們家還順帶解決了react-router-redux的問題(試想router作為state下的routing模塊卻不懂用Immutable該多呵呵):

https://github.com/gajus/redux-immutable#using-with-react-router-redux

說了這么多,怎么用呢

首先你的項目是react + router + redux的標(biāo)配。
然后你要引入Immutable。

那么你該這樣:

  1. 引入redux-immutable
  2. 按照redux-immutable的README.md把history什么的配置好(Ctrl+C, Ctrl+V)
  3. 所有reducer合并的時候換用redux-immutable的combineReducers
  4. 所有數(shù)據(jù)出入state用Immutable.js的Immutable.ListImmutable.Map(這個才是正題)

還有什么要注意的嗎?

組件的問題:

從redux過來的思想是把組件分成Smart和Dumb。Smart組件負(fù)責(zé)把數(shù)據(jù)接進來,Dumb組件負(fù)責(zé)使用數(shù)據(jù),并只關(guān)注props。所以Immutable要覆蓋Smart和Dumb嗎?

我個人觀點是這樣的:
Dumb組件基本都是要抽象出來給多個項目共用的。這部分組件不支持Immutable應(yīng)該更好些,否則就被綁死在Immutable上了。

那這么說,Dumb里的數(shù)據(jù)是JavaScript原生的,豈不是享受不到Immutable帶來的好處?
數(shù)據(jù)已經(jīng)復(fù)制給了組件,為了兼容性犧牲一點這個也沒啥吧?

這個想法背后的結(jié)論就是:
redux概念里的Container在做state與props之間,props與dispatch之間的對接的時候,也同時做了Immutable與原生的相互轉(zhuǎn)換。(Adapter Pattern吧)

測試的時候:

你會想console.log一下當(dāng)前的數(shù)據(jù)吧,把Immutable.List打出來看著很累的,建議用console.log(imtb.toJS())

可是debug的時候呢?

題外話

如果這些特性是JavaScript本身內(nèi)置的就好了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容