Redux進階系列1: React+Redux專案結構最佳實踐
React + Redux 是React生態中使用最頻繁的技術棧,但關於如何組織React+Redux的專案結構,一直都有多種聲音。本文將討論其中最常用的3種專案結構,並給出個人的最佳實踐。
按照型別
這裡的型別指的是一個檔案在專案中充當的角色型別,即這個檔案是一個component,還是一個container,或者是一個reducer等,充當component、container、action、reducer等不同角色的檔案,分別放在不同的資料夾下,這也是Redux官網示例所採用的專案結構。這種結構如下所示:
actions/ a.js b.js components/ a1.js
使用這種結構組織專案,每當增加一個新功能時,需要在containers和components資料夾下增加這個功能需要的元件,還需要在actions和reducers資料夾下,分別新增Redux管理這個功能使用到的action和reducer,如果action type是放在另外一個資料夾的話,還需要在這個資料夾下增加新的action type檔案。所以,開發一個功能時,你需要頻繁的切換路徑,修改不同的檔案。當專案逐漸變大時,這種專案結構是非常不方便的。
按照功能
一個功能模組對應一個資料夾,這個功能所用到的container、component、action、reducer等檔案,都存放在這個資料夾下。如下所示:
feature1/ components/ actions.js container.js index.js reducer.js feature2/ components/ actions.js container.js index.js reducer.js index.js rootReducer.js
這種專案結構的好處顯而易見,一個功能中使用到的元件、狀態和行為都在同一個資料夾下,方便開發,易於功能的擴充套件,Github上很多腳手架也選擇了這種目錄結構,如
Ducks
Ducks其實是對一種新的Redux專案結構的提議。它提倡將相關聯的reducer、action types和action寫到一個檔案裡。本質上是以應用的狀態作為模組的劃分依據,而不是以介面功能作為劃分模組的依據。這樣,管理相同狀態的依賴都在同一個檔案中,不管哪個容器元件需要使用這部分狀態,只需要在這個元件中引入這個狀態對應的檔案即可。這樣的一個檔案(模組)如下:
// widget.js // Actions const LOAD = 'widget/LOAD'; const CREATE = 'widget/CREATE'; const UPDATE = 'widget/UPDATE'; const REMOVE = 'widget/REMOVE'; const initialState = { widget: null, isLoading: false, } // Reducer export default function reducer(state = initialState, action = {}) { switch (action.type) { LOAD: //... CREATE: //... UPDATE: //... REMOVE: //... default: return state; } } // Action Creators export function loadWidget() { return { type: LOAD }; } export function createWidget(widget) { return { type: CREATE, widget }; } export function updateWidget(widget) { return { type: UPDATE, widget }; } export function removeWidget(widget) { return { type: REMOVE, widget }; }
整體的目錄結構如下:
components/ (應用級別的通用元件) containers/ feature1/ components/ (功能拆分出的專用元件) feature1.js (容器元件) index.js (feature1對外暴露的介面) redux/ index.js (combineReducers) module1.js (reducer, action types, actions creators) module2.js (reducer, action types, actions creators) index.js
在前兩種專案結構中,當container需要使用actions時,可以通過
import * as actions from 'path/to/actions.js'
方式,一次性把一個action檔案中的所有action creators都引入進來。但在使用Ducks結構時,action creators和reducer定義在同一個檔案中,import *
的匯入方式會把reducer也匯入進來(如果action types也被export,那麼還會匯入action types)。我們可以把action creators和action types定義到一個名稱空間中,解決這個問題。修改如下:// widget.js // Actions export const types = { const LOAD : 'widget/LOAD', const CREATE : 'widget/CREATE', const UPDATE : 'widget/UPDATE', const REMOVE : 'widget/REMOVE' } const initialState = { widget: null, isLoading: false, } // Reducer export default function reducer(state = initialState, action = {}) { switch (action.type) { types.LOAD: //... types.CREATE: //... types.UPDATE: //... types.REMOVE: //... default: return state; } } // Action Creators export const actions = { loadWidget: function() { return { type: types.LOAD }; }, createWidget: createWidget(widget) { return { type: types.CREATE, widget }; }, updateWidget: function(widget) { return { type: types.UPDATE, widget }; }, removeWidget: function(widget) { return { type: types.REMOVE, widget }; } }
這樣,我們在container中使用actions時,可以通過
import { actions } from 'path/to/module.js'
引入,避免了引入額外的物件,也避免了import時把所有action都列出來的繁瑣。現在的Ducks結構就是我專案中正在使用的專案結構,用起來還是很順暢的,歡迎大家提出改進建議!
相關推薦
Redux進階系列1: React+Redux專案結構最佳實踐
React + Redux 是React生態中使用最頻繁的技術棧,但關於如何組織React+Redux的專案結構,一直都有多種聲音。本文將討論其中最常用的3種專案結構,並給出個人的最佳實踐。 按照型
Redux進階系列1:React+Redux專案結構最佳實踐
React + Redux 是React生態中使用最頻繁的技術棧,但關於如何組織React+Redux的專案結構,一直都有多種聲音。本文將討論其中最常用的3種專案結構,並給出個人的最佳實踐。按照型別這裡的型別指的是一個檔案在專案中充當的角色型別,即這個檔案是一個component,還是一個container,
【 D3.js 進階系列 — 1.0 】 CSV 表格檔案的讀取
在入門系列的教程中,我們常用 d3.json() 函式來讀取 json 格式的檔案。json 格式很強大,但對於普通使用者可能不太適合,普通使用者更喜歡的是用 Microsoft Excel 或 OpenOffice Calc 等生成的表格檔案,因為簡單易懂,容易編輯。
【 D3.js 進階系列 — 1.1 】 其他表格檔案的讀取
CSV 表格檔案是以逗號作為單元分隔符的,其他還有以製表符 Tab 作為單元分隔符的 TSV 檔案,還有人為定義的其它分隔符的表格檔案。本文將說明在 D3 中如何讀取它們。 1. TSV 表格檔案是什麼 TSV(Tab Separated Values),製表分隔值,它
SilkTest高階進階系列1-用textract來識別文字
在以前的文章中,我簡單介紹過如何使用SilkTest中的OCR功能識別介面或者是bmp圖片上的文字內容。也提到過silktest自帶一個ocr識別的pattern庫,該庫可以識別windows下的某些字型。不過這些字型都是常見的字型,種類有限,對於某些特殊的字型,預設是無法
react-redux進階
react-redux進階一、 安裝: npm install redux react-redux 二、入口文件:index.jsx: 引入: 創建reducer: 創建容器: 將容器綁定到屬性: 完整代碼: var React = require(‘react‘) var ReactDom = re
React (5) Redux 進階
1. UI 元件 render()函式放在另外一個單獨的UI.js 檔案和動作行為分開 UI 上面所用的資料和函式, 通過父元件傳遞過來,用 this.props 來接收 UI 元件下面: import 'antd/dist/antd.css';
Redux進階---異步和中間件
src clas 復制 undle 行處理 pre reducer 明顯 dom Redux中間件,其實就是一個函數, 當我們發送一個action的時候,先經過它,我們就可以對action進行處理,然後再發送action到達reducer, 改變狀態,這時我們就可以在中
Python進階系列連載(1)——那些容易被忽略的問題(上)
本篇我們來聊一聊一些在入門部分容易被忽略的問題 int()強制轉換浮點數 在int()的強制轉換浮點數時候,不管是正數還是負數,只取整數部分。 注意:這裡不是向上或者向下取整,也不是四捨五入。 無限遞迴 還記得我們講的俄羅斯套娃麼,還記得
Flutter redux 進階
目的 認識Flutter Redux侷限性 引入Middleware必要性 全方位整合UT Flutter Redux初代實現侷限性 UT不好覆蓋 頁面 初代實現一個頁面的結構是這樣的: class XXXScreen extends StatefulWidget {
Redux進階(Immutable.js)
更好的閱讀體驗 更好的閱度體驗 Immutable.js Immutable的優勢 1. 保證不可變(每次通過Immutable.js操作的物件都會返回一個新的物件) 2. 豐富的API 3. 效能好 (通過字典樹對資料結構的共享) Immutable的問題 1. 與原生JS互動不友好
Redux進階(像VUEX一樣使用Redux)
更好的閱度體驗 前言 redux的問題 方案目標 如何實現 思考 前言 Redux是一個非常實用的狀態管理庫,對於大多數使用React庫的開發者來說,Redux都是會接觸到的。在使用Redux享受其帶來的便利的同時, 我們也深受其問題的困擾。 redux的問題 之前在另
Redux進階(一)
State的不可變化帶來的麻煩 在用Redux處理深度複雜的資料時會有一些麻煩。由於js的特性,我們知道當對一個物件進行復制時實際上是複製它的引用,除非你對這個物件進行深度複製。Redux要求你每次你返回的都是一個全新的State,而不是去修改它。這就要求我們要對原來的State進行深度複製。這往往帶來複雜的
【 D3.js 進階系列 — 2.1 】 力學圖的事件 + 頂點的固定
本章討論在力學圖中常用到的事件( Event ),然後對【進階 - 第 2.0 章】的人物關係圖進行改進,使使用者能夠固定拖拽的物件。 force.on("tick", function(){ });這裡的 force 是之前程式碼中定義的佈局( Layout )
HTML5 進階系列:indexedDB 數據庫
連接數據庫 function request html5 客戶端 前言在 HTML5 的本地存儲中,有一種叫 indexedDB 的數據庫,該數據庫是一種存儲在客戶端本地的 NoSQL 數據庫,它可以存儲大量的數據。從上篇:HTML5 進階系列:web Storage ,我們知道
C#進階系列——WebApi 異常處理解決方案(轉)
機制 輸出 ges 如果 但是 rom lba slist 解決 出處:http://www.cnblogs.com/landeanfen/p/5363846.html 閱讀目錄 一、使用異常篩選器捕獲所有異常 二、HttpResponseException自
C#進階系列——WebApi 接口測試工具:WebApiTestClient
spa type 區域 all 手動 shee 找到 網絡 打開文件 C#進階系列——WebApi 接口測試工具:WebApiTestClient 前言:這兩天在整WebApi的服務,由於調用方是Android客戶端,Android開發人員也不懂C#語法,API裏
C#進階系列——WebApi 路由機制剖析:你準備好了嗎?
事先 blank path can tex 全局配置 dex 找不到 save 前言:從MVC到WebApi,路由機制一直是伴隨著這些技術的一個重要組成部分。 它可以很簡單:如果你僅僅只需要會用一些簡單的路由,如/Home/Index,那麽你只需要配置一個默認路由就能簡
C#進階系列——WebApi 跨域問題解決方案:CORS
dea ati ice pro target default 異常 測試工具 復雜 前言:上篇總結了下WebApi的接口測試工具的使用,這篇接著來看看WebAPI的另一個常見問題:跨域問題。本篇主要從實例的角度分享下CORS解決跨域問題一些細節。 WebApi系列文章
Jenkins進階系列之——09配置Linux系統ssh免密碼登陸
dom pub tar finger cnblogs pan 改變 art home ssh認證的完整描述:https://www.ibm.com/developerworks/cn/linux/security/openssh/part1/ 說明:點我去查看 今天我們只說