天天看點

在React中使用Redux

webpack.prod.config.js中缺少了對path庫的引用,執行建構<code>npm run build:prod</code>的時候失敗。在檔案開始的地方引入node.js的path庫就可以了。

package.json裡面定義了一個build:dev的腳本,這個腳本其實有點多餘,不過有時候需要打包測試版本的檔案,是以還是需要存在。主要有個問題是webpack.dev.config.js中output節點下錯誤定義了path的值為根目錄'/',這在使用<code>npm start</code>指令啟動運作時打包的時候看不出問題,但是在使用<code>npm run build:dev</code>時會出現無法寫檔案到根目錄的權限錯誤。隻要把path的值改掉就可以。<code>path: config.publicPath</code>改成<code>path: config.staticPath,publicPath: config.publicPath</code>。

css-loader和less-loader導出的樣式類名太長,還是把localIdentName中的path部分去掉比較好看。

安裝依賴的指令如下:

redux不用說了,我是把它當成一個本地資料庫使用,react-redux幫助你完成資料訂閱,redux-thunk可以放你實作異步action,redux-logger是redux的日志中間件。

在開始介紹之前我想先就redux的使用發表一些自己的看法:

前文說了我把redux當成一個本地資料庫,是以我傾向于把redux封裝類似于mvc中的Model的角色,獨立為一層。這與另一種觀點——我在公司的項目更傾向于把每個頁面當成一個獨立子產品,每個子產品維護自己的reducer和action的觀點,有所出入。

我的做法可以更好地實作reducer的複用。而對我自己來說更重要的好處是集中修改。更适合小項目或者獨自開發一個項目的場景。

我公司的項目的做法對多人協同開發更有利,畢竟每個人維護好自己的代碼就可以了。公司項目的這種方法有幾個問題讓我比較難以接受:

第一個是子產品越多reducer和action的定義越多,很多時候這些代碼都是差不多的。

更重要的是第二個問題:子產品資料在store裡面的存儲是直接在根state下面排列下來的,根state的資料格式樣式有點像這樣:

項目的原意是希望每個子產品的保持獨立,但實際上使用的時候卻是有極大的可能出現aModule同時使用aModuleData和bModuleData的情況。這跟每個人維護自己的代碼的初衷有悖,也沒有發揮好redux的真正能力。

還有一個小問題是reducer的組織通常影響着應用資料state的樣式,把reducer分散到每個子產品之後,state的形式在代碼上很難直管地反映出來,特别是當子產品是動态加載的時候更甚。不過借助logger等工具可以解決。

關于這塊的争議Redux的教程中有提及。

無論代碼怎麼布局,使用redux的方法主要還是三步曲:建立store、建立action、建立reducer。而在這之後才是與業務或者元件相關的資料處理和展示。

先看一下我的做法的代碼布局:

建立store的代碼集中在model/index.js中,model/actions/.js和model/reducer/.js裡面分别是寫action建立函數和reducer函數的地方,根據子產品可以自己DIY。

model/index.js的代碼如下:

model/actions/index.js的代碼如下:

這裡定義了一個名叫login的異步actionCreator以及三個普通的actionCreator。

actionCreator被某個元件調用後會向store發送action,然後被reducer處理,reducer定義在model/reducers/index.js中,代碼如下:

這就完成了三步曲了。上面的代碼簡單地模拟了登入的動作。登入頁面用到的資料存放在loginPageData中,登陸後擷取到的目前登入使用者資料存儲在實體資料entities中。

接下來要把redux和react聯系起來,也就是把redux的store中的資料交給react的元件使用。

第一步需要挂載redux的store到react,為react提供資料支援。最簡單的做法是找到應用的根元件(我這裡是BasicExample.js),然後在它的render函數中最外層添加Providor标簽。代碼片段如下:

紅線部分畫出了改動點,從model/index.js中導出了store對象,通過react-redux提供的Providor标簽挂載到react中,為react提供資料支援。

看最後的紅線中,我們在Home元件裡面添加了這次的測試例子ReduxDemo。它的代碼如下:

代碼的重點在connect函數。這個函數也是由react-redux提供的。使用它可以包裝普通的展示元件(這裡是ReduxDemo——隻負責展示資料),然後傳回一個容器元件。connect函數通過第一個參數讓展示元件訂閱了來自store的資料;通過第二個參數讓展示元件預設可以dispatch各種action。

這個例子在ReduxDemo挂載完成後調用login接口模拟登陸。傳回結果被塞到store中(資料格式由先前寫好的reducers的組織方式決定)。頁面根據store中的資料展示内容。由于login發出的遠端請求是假的,是以這裡總是失敗,是以會顯示失敗的内容。

關于redux的使用介紹到此結束。

其實在上面的代碼中我已經悄悄地提及了兩個輔助庫,也是我想在這裡推薦的兩個庫:

開發工具redux-devtools:結合各種其他庫可以實作可視化的調試界面。

資料規範化工具normalizr:規範化組織資料。經過三個項目的體驗後,個人非常推薦使用這個庫,可以讓應用的資料組織更清晰、減少備援資料、減少因資料重新整理導緻的性能影響。

暫時不在這裡展開介紹,有興趣的可以到github上查一下文檔。

源碼下載下傳位址:h tt ps : / /p a n . b ai d u . c o m /s / 1 d E N Y fu h 

本文轉自xmgdc51CTO部落格,原文連結:http://blog.51cto.com/12953214/1942932 ,如需轉載請自行聯系原作者