自由來自于對自身力量的限度和上天所設置的自然之限度的了解库菲。接受生命的限度整袁,而不與其抗爭菠齿,我們才能獲得自由。相反坐昙,如果我們屈從于一時之念绳匀,想得到我們無法控制的事物時,我們就會失去自由炸客。
1.功能分析
完成一個todos應用疾棵,對于處理每一個todo的方法應該有addTodo,deleteTodo痹仙,reverseTodo是尔。同時在展示todo的時候還得篩選一下哪些todo應該展示-filterTodo。對于一個應用來說开仰,我們第一步應該先著手設計一下store所維護的state對象拟枚。通過我們在上面提到的對todo的操作方法來看,在應用中那是必須要有一個todos狀態(tài)的众弓,而又還得進行一下篩選恩溅,并且這個篩選條件又是可以變化的。因此這個篩選條件也得是一個狀態(tài)谓娃。所以我們的storeState可以這樣設計:
{
"todos": Array,
"filter": String
}
問題是我們應該如何設計每一個todo脚乡?如果把每一個事項抽象成一個對象的話,那么我們先來看看對這個對象進行操作的方法有哪些滨达,在上面也提到了奶稠,分別有addTodo俯艰,deleteTodo,reverseTodo锌订。對于addTodo來說蟆炊,它要將一個由輸入文本加工而來的 todo添加到todos數組中。對于deleteTodo來說瀑志,它要將todos數組中指定位置的todo給刪除涩搓。對于reverseTodo來說,它要將todos數組中指定位置的todo給翻轉一下狀態(tài)劈猪。對于filterTodo來說昧甘,我們要根據todos數組中每一個todo的完成狀態(tài)來決定是否顯示。通過上面的分析战得,我們的每一個todo應該長什么樣就已經很清楚了:
{
"text": String,
"id": Number,
"finished": Boolean
}
到這里充边,我們的store所維護的狀態(tài)對象的設計就已經大致完成了,后期如果發(fā)現(xiàn)不足的話常侦,那么我們將會繼續(xù)更改浇冰。那么現(xiàn)在可以著手思考第二個問題,如何架構應用聋亡。
通過上面的分析肘习,我們可以明白我們的todo應用有這么幾個處理事項的方法:addTodo,deleteTodo坡倔,reverseTodo漂佩,filterTodo,showTodo罪塔。很顯然這些方法都需要跟store進行交互投蝉。雖然對于我們的todos應用來說,我們可以把所有的reducer以及actionCreater和actionTypes文件合并到各自獨屬的那個文件中征堪,但是呢瘩缆,這樣做的話,如果我們的應用所需要維護的狀態(tài)太多以及響應類型太多的話佃蚜,這樣的一個架構會使得我們的代碼太過臃腫庸娱,不便于日后的項目維護。因此爽锥,我們應該將這這部分邏輯轉移到各自的組件中去涌韩。我們上面也提到了,有增加組件氯夷,刪除組件臣樱,翻轉組件,篩選組件,展示組件的功能雇毫。如果我們把這幾個功能每一個都獨立出來實現(xiàn)的話玄捕,那么我們將需要多個功能子文件,當項目一大起來的話棚放,功能子文件將會井噴式增多枚粘。同時,對于這些功能來說飘蚯,挺多功能是使用同一個store所維護的狀態(tài)的馍迄,那么問題來了,我們的combineReducer()函數是否接受多個reducer對應同一個store所維護的state字段局骤?先拋開這個不說攀圈,如果我們將每個功能都分開來的話蝗羊,那么對于某些功能來說悍缠,它是強烈依賴某些功能的度帮,比如對于展示功能來說它很依賴增添組件功能以及翻轉傻工,刪除功能以及篩選條件,而為了實現(xiàn)這種依賴性骂维,我們的組件將會是強耦合的稀轨,而這不利于一個系統(tǒng)填物。那么問題來了冰单,我們如何根據功能來劃分組件呢幌缝?一般的,我們可以根據下面這個原則劃分:是否依賴store中的同一部分狀態(tài)球凰,如果是的話狮腿,那么最好將其放在同一個組件中實現(xiàn)腿宰。
對于上面所分析的功能:增加呕诉,刪除,反轉吃度,篩選甩挫,展示。對于增加功能來說椿每,很顯然它是與todos進行交互的伊者;對于刪除功能來說,todos间护;對于反轉功能來說亦渗,todos;對于展示功能來說汁尺,todos法精,filter;對于篩選功能來說,filter搂蜓。
此時就很明顯了狼荞,我們應該把增加,刪除帮碰,反轉相味,展示放在同一個組件中todos實現(xiàn)。篩選功能放在filter組件中實現(xiàn)殉挽。這個時候的架構設計還是有一點輕微的耦合的丰涉,不過程度不高——展示組件時需要讀取store所維護的filter字段將它拿去去與filterTypes做比較,因此此時todos需要引入外部的filter組件的actionTypes文件斯碌。這個時候昔搂,應用的架構設計就已經基本明確了。
介紹一下redux庫中的combineReducers方法输拇,這個方法可以將多個reducer函數組合成一個結果函數返回摘符,這個結果函數會囊括前面各個reducer函數的工作。問題是combineReducers函數接受的是一個對象策吠,這個對象的鍵值就是我們的reducer函數所需要的storeState中的相應狀態(tài)名逛裤,值就是reducer函數了。
因此猴抹,對于我們每個組件來說带族,它的reducer函數所接受的第一個參數state是自己所需要的,而不是store所維護的整個狀態(tài)蟀给,同時蝙砌,對于一個復雜的應用來說我們一般都很少在應用的根文件中設定store的初始值了,那么該怎么做呢跋理?畢竟初始值是必需的——此時我們就會在每個功能組件的reducer文件中為自己所需要的store的某部分state設定初值择克,至于這個state的名字,前面也提到了前普,在combineReducers函數會被作為參數對象的鍵名被綁定肚邢。
第二個需要注意的地方是,盡管在每個功能文件中里reducer文件所接受的state是局部的拭卿。但是對于mapStateToProps來說骡湖,他所接受到的state那可就是整個storeState對象了。
2.總結
webpack打包過程中遇到了一些小問題:
return (
<ul>
todos.map()
</ul>
)
上面那個是錯的峻厚,由于沒有熟悉JSX規(guī)范:在JSX中出現(xiàn)的js表達式必須在{}里面响蕴,因此對于上面加一對大括號就可以了。