這是Webpack+React系列設定過程記錄的第六篇。其他內容請參考:
第一篇:使用webpack、babel、react、antdesign設定單頁應用開發環境
第二篇:使用react-router實作單一頁面應用程式路由
第三篇:最佳化單一頁面開發環境:webpack與react的執行時間打包與熱更新
第四篇:React配合Webpack實作程式碼分割與非同步載入
第五篇:分離Webpack開發環境與生產環境的設定
#第六篇:在React中使用Redux
這篇文章的主要內容包括: 1. 修改一下之前存在的問題;
#2. 在框架中引入redux,使用一個範例簡單介紹redux的使用方法;
3. 其他redux輔助庫。
webpack.prod.config.js中缺少了對path函式庫的引用,執行建置npm run build:prod
的時候失敗。在檔案開始的地方引入node.js的path函式庫就可以了。
package.json裡面定義了一個build:dev的腳本,這個腳本其實有點多餘,不過有時候需要打包測試版本的文件,所以還是需要存在。主要有個問題是webpack.dev.config.js中output節點下錯誤定義了path的值為根目錄'/',這在使用npm start
命令啟動運行時打包的時候看不出問題,但在使用npm run build:dev
時會出現無法寫入檔案到根目錄的權限錯誤。只要把path的值改掉就可以。 path: config.publicPath
改成path: config.staticPath,publicPath: config.publicPath
。
css-loader和less-loader匯出的樣式類別名稱太長,還是把localIdentName中的path部分去掉比較好看。
安裝依賴的指令如下:
npm install --save redux react-redux redux-thunk npm install --save-dev redux-logger
redux不用說了,我是把它當成一個本地資料庫使用,react-redux幫助你完成資料訂閱,redux-thunk可以放你實作異步action,redux-logger是redux的日誌中間件。
在開始介紹之前我想先就redux的使用發表一些自己的看法:
前文說了我把redux當成一個本地資料庫,因此我傾向於把redux封裝類似mvc中的Model的角色,獨立為一層。這與另一個觀點——我在公司的專案更傾向於把每個頁面當成一個獨立模組,每個模組維護自己的reducer和action的觀點,有所出入。
我的做法可以更好地實現reducer的複用。而對我自己來說更重要的好處是集中修改。更適合小專案或獨自開發一個專案的場景。
我公司的專案的做法對多人協同開發更有利,畢竟每個人維護好自己的程式碼就可以了。公司專案的這種方法有幾個問題讓我比較難以接受:
第一個是模組越多reducer和action的定義越多,很多時候這些程式碼都是差不多的。
更重要的是第二個問題:模組資料在store裡面的儲存是直接在根state下面排列下來的,根state的資料格式樣式有點像這樣:
{ aModuleData:{...}, bModuleData:{...}, cModuleData:{...}, dModuleData:{...}, ... }
專案的原意是希望每個模組的保持獨立,但實際上使用的時候卻是有極大的可能出現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上查一下文件。
以上是在React中使用Redux的實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!