在React中使用Redux

来源:http://www.cnblogs.com/developerdaily/archive/2017/06/28/7090851.html
-Advertisement-
Play Games

這是Webpack+React系列配置過程記錄的第六篇。其他內容請參考: 第一篇:使用webpack、babel、react、antdesign配置單頁面應用開發環境 第二篇:使用react-router實現單頁面應用路由 第三篇:優化單頁面開發環境:webpack與react的運行時打包與熱更新 ...


這是Webpack+React系列配置過程記錄的第六篇。其他內容請參考:

這篇文章的主要內容包括: 1. 修改一下之前存在的問題; 
2. 在框架中引入redux,使用一個例子簡單介紹redux的使用方法; 
3. 其他redux輔助庫。

修複遺留問題

  1. webpack.prod.config.js中缺少了對path庫的引用,執行構建npm run build:prod的時候失敗。在文件開始的地方引入node.js的path庫就可以了。
  2. 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
  3. css-loader和less-loader導出的樣式類名太長,還是把localIdentName中的path部分去掉比較好看。

redux

安裝redux

安裝依賴的命令如下:

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當成一個本地資料庫,因此我傾向於把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

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

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

代碼佈局

創建store的代碼集中在model/index.js中,model/actions/.js和model/reducer/.js裡面分別是寫action創建函數和reducer函數的地方,根據模塊可以自己DIY。

model/index.js的代碼如下:

model/index.js的代碼

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

model/actions/index.js的代碼

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

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

model/reducers/index.js的代碼

這就完成了三步曲了。上面的代碼簡單地模擬了登錄的動作。登錄頁面用到的數據存放在loginPageData中,登陸後獲取到的當前登錄用戶數據存儲在實體數據entities中。

接下來要把redux和react聯繫起來,也就是把redux的store中的數據交給react的組件使用。

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

掛載redux的store到react

紅線部分畫出了改動點,從model/index.js中導出了store對象,通過react-redux提供的Providor標簽掛載到react中,為react提供數據支持。

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

ReduxDemo代碼

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

這個例子在ReduxDemo掛載完成後調用login介面模擬登陸。返回結果被塞到store中(數據格式由先前寫好的reducers的組織方式決定)。頁面根據store中的數據展示內容。由於login發出的遠程請求是假的,所以這裡總是失敗,因此會顯示失敗的內容。

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

redux輔助庫

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

  1. 開發工具redux-devtools:結合各種其他庫可以實現可視化的調試界面。
  2. 數據規範化工具normalizr:規範化組織數據。經過三個項目的體驗後,個人非常推薦使用這個庫,可以讓應用的數據組織更清晰、減少冗餘數據、減少因數據刷新導致的性能影響。

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

源碼下載地址:https://pan.baidu.com/s/1dENYfuh


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 簡介 貝塞爾曲線是可以做出很多複雜的效果來的,比如彈跳球的複雜動畫效果,首先加速下降,停止,然後彈起時逐漸減速的效果。 使用貝塞爾曲線常用的兩個網址如下: 緩動函數:http://www.xuanfengge.com/easeing/easeing/ cubic-bezier:http://cubi ...
  • 1.如何使用vuex來保存數據(需要傳參的情況下) 實例說明:登錄->緩存用戶信息->跳轉到首頁->從state獲取用戶信息顯示在頁面上 step1: 新建store.js作為初始化vuex的主文件,可在裡面創建state對象,緩存數據欄位,初始化vuex, 目錄結構如下: store.js代碼如下 ...
  • 如果你是一個人在自學前端開發,或者是對前端開發有比較濃厚的興趣正想踏入前端領域,只要你在前端自學路上遇到了自己無法解決的技術難題,那麼儘管將你的疑惑交給我的小伙伴兒們吧,我們都是一群在前端自學路上摸爬滾打的有志青年,希望你可以來和我們共同交流。同時也希望你能獻出自己的一份力,幫助我的小伙伴兒們解決他 ...
  • 一. 簡介 一個用於顯示多種不同類型圖片的React組件,包括網路圖片、靜態資源、臨時的本地圖片、以及本地磁碟上的圖片(如相冊)等。從0.14版本開始,React Native提供了一個統一的方式來管理iOS和Android應用中的圖片。要往App中添加一個靜態圖片,只需把圖片文件放在代碼文件夾比如 ...
  • 菜單導航,《JS面向對象筆記一》, 參考書籍:阮一峰之《JavaScript標準參考教程》 一、構造函數和new命令 二、this關鍵字 三、構造函數和new命令 四、構造函數和new命令 五、構造函數和new命令 六、構造函數和new命令 七、構造函數和new命令 八、構造函數和new命令 一、構 ...
  • 方法一: 分別獲取所需數據元素,DOM結構外層不用包form標簽(適用於數據量少,數據元素分散於整個頁面) 方法二: 需要包裹form標簽(適用於數據量大,元素集中) html代碼: ...
  • apply和call的方法是一模一樣的,都是用來改變方法的this關鍵字,並且把方法執行:而且在嚴格模式和非嚴格模式下對於第一個參數是null/undefined這種情況的規律是一樣的; bind:這個方法在IE6-8下不相容 ->和call和apply類似都是用來改變this關鍵字的 ...
  • $("#iframeId").on("load", function(event){//判斷 iframe是否載入完成 這一步很重要 $("#divId",this.contentDocument).click(function(){//添加點擊事件 alert("就是這樣"); }); }); ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...