摘要:但是把這些組件串起來也有很多邏輯,如果每個類似的模塊都重復寫,任何一個小的邏輯發生變化,都可能需要修改所有的模塊實現。接下來我們是的類似的,也是通過和來唯一地標識一個模塊。當然每個模塊可能會有不同的,這個也可以通過的入參來設置。
我們開發一個新產品的時候,通常會先抽象出一些公用的組件,然后通過這些組件來拼裝成頁面。不知道大家有沒有發現,這種開發方式帶來的問題是一個團隊內經常會有這樣的場景:
A 已經開發了一個 XX 表格模塊,B 要開發一個類似的 YY 表格模塊,然后 B 通常是去把 A 的代碼 copy 一下,修改一些東西;或者不巧 B 不知道 A 已經開發 XX 表格,然后 B 又得一行行的寫一些類似的代碼。
造成這種問題的原因簡單的說就是:組件抽象的粒度太單一。接下來我們會通過兩個例子來講述問題及我們如何解決這樣的問題的。
一個簡單的組件 - Switch首先我們看一個簡單的 Switch 組件,如果一個產品中有常用的兩種切換功能:
如果使用之前封裝的基礎組件組件 Switch 來實現,我們需要如下調用:
趨勢 列表
這種組件抽象方式(實現省略)好處就是通用性強,但帶來一些問題:
每個人都需要維護選項的展示名稱和順序之間的關系
調用代碼較長,有冗余
于是,我們對這類組件進行了重構,希望讓每個組件使用更加簡單,只需要關系具體的狀態即可。具體的做法就是開發一個 Generator —— generateSwitch 來生成常用的切換組件:
export const generateSwitch = (name, options) => {
const propTypes = {
className: PropTypes.string,
activeKey: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
onChange: PropTypes.func.isRequired,
};
const Switch = (props) => {
...
return (
{
options.map((entry, index) => (
...
))
}
);
};
Switch.propTypes = propTypes;
Switch.displayName = name;
return Switch;
};
export const ASwitch = generateSwitch("ABSwitch", [
{ name: "AA", key: "a" },
{ name: "BB", key: "b" },
]);
export const BSwitch = generateSwitch("CDSwitch", [
{ name: "CC", key: "c" },
{ name: "DD", key: "d" },
]);
這種做法就可以解決上面說的問題:
比常見的切換組件使用更加便利,調用代碼一行就夠了,而且能夠起到統一參數的作用;
對外暴露生成函數 generateSwitch 也能保證通用性。
更復雜的例子 - 業務模塊下面以一個表格業務為例,常見的表格模塊如下:
在開發這個模塊的時候,雖然每個小區塊我們都抽取了相應的組件,如 Selector, Table, Switch, Pagination 等。但是把這些組件串起來也有很多邏輯,如果每個類似的模塊都重復寫,任何一個小的邏輯發生變化,都可能需要修改所有的模塊實現。所以這時候我們想做的事情就是:這個模塊本身也是一個組件,我們只需要通過一些配置生成不同的模塊,而不是重復的 copy 代碼,然后修改一些差異的地方。
在這里碰到的一個問題是,我們整個系統是使用 Redux 來管理數據的,整個項目的 Store 結構如下:
每個業務模塊會去 connect 相應的數據以及 actions ,每個模塊都有相應的 reducer。并且每個卡片的 action 也需要做到全局唯一,所以我們給模塊的 UI Component 以及 reducer 分別開發了相應的 Generator。
首先來看 UI Component 的 Generator:
function generateAbcModule({pageName, moduleName}) { const ACTION_PREFIX = `${pageName}/${moduleName}`; const LOAD = ACTION_PREFIX + "LOAD"; ... function load(url, params, id) { return (dispatch, getState) => { const state = getState(); ... return dispatch({ type: LOAD, .... }); }; } @connect((state, props) => { const moduleState = state[pageName][moduleName]; return { ...moduleState, }; }, { load, }) class AbcModule extends Component { ... } return AbcModule; }
通過代碼發現,我們把 actionCreators 與 UI 放在了一起,然后通過 pageName 和 moduleName 來唯一地標識一個模塊,拼裝這兩個參數作為 action 的前綴,從而達到每個模塊的 action 是全局唯一的。
接下來我們是 reducer 的 Generator:
function generateAbcModuleReducer({pageName, moduleName, defaultIndexes}) { const ACTION_PREFIX = `${pageName}/${moduleName}/`; const LOAD = ACTION_PREFIX + "LOAD"; const initialState = { indexes: defaultIndexes, ... }; return function AbcModuleReducer(state = initialState, action) { switch (action.type) { case LOAD: return { ...state, isLoading: true, ... }; ... } };
類似的,reducer Generator 也是通過 pageName 和 moduleName 來唯一地標識一個模塊。當然每個模塊可能會有不同的 initialState,這個也可以通過 generateAbcModuleReducer 的入參來設置。
總結上面這種使用 Generator 來封裝業務模塊的方法,能夠在一定程度上減少重復代碼,加快開發速度,不過如果業務發展的很快,有可能會導致業務模塊組件 props 泛濫 的問題。
以上面的排行卡片為例,可變的東西就非常多,相應的就需要很多的 props 來配置,所以我們也需要根據具體的業務來把握是否要進行抽象。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79720.html
摘要:精讀源碼一共行,我們分析一下其精妙的方式。更多討論討論地址是精讀新用法如果你想參與討論,請點擊這里,每周都有新的主題,周末或周一發布。前端精讀幫你篩選靠譜的內容。 1 引言 很高興這一期的話題是由 epitath 的作者 grsabreu 提供的。 前端發展了 20 多年,隨著發展中國家越來越多的互聯網從業者涌入,現在前端知識玲瑯滿足,概念、庫也越來越多。雖然內容越來越多,但作為個體的...
摘要:后面會利用這個框架來做實踐。接下來就是我們要繼續探討的同構同構數據處理的探討我們都知道,瀏覽器端獲取數據需要發起請求,實際上發起的請求就是對應服務端一個路由控制器。是有生命周期的,官方給我們指出的綁定,應該在里來進行。 眾所周知,目前的 WEB 應用,用戶體驗要求越來越高,WEB 交互變得越來越豐富!前端可以做的事越來越多,去年 Node 引領了前后端分層的浪潮,而 React 的出現...
摘要:寫好的單元測試,對開發速度項目維護有莫大的幫助。我認為單元測試的上下文存在于敏捷中。接下來一小節,就可以正式進入如何做的環節了如何寫好單元測試。前面說到,我們對單元測試寄予 寫好的單元測試,對開發速度、項目維護有莫大的幫助。前端的測試工具一直推陳出新,而測試的核心、原則卻少有變化。與產品代碼一并交付可靠的測試代碼,是每個專業開發者應該不斷靠近的一個理想之地。本文就圍繞測試講講,為什么我...
摘要:盲目使用替換后可能會導致預期意外的結果。在中,許多種方法來處理函數的參數默認值,參數數量,參數命名。此外,處理后的值,無論是解決還是拒絕的結果值,都是不可改變的。 這是一個 ES2015(ES6) 的Cheatsheet,其中包括提示、小技巧、最佳實踐和一些代碼片段,幫助你完成日復一日的開發工作。 Table of Contents var 與 let / const 聲明 代碼執行...
摘要:模塊化以項目中普遍會有的文件為例,實現導出再在其他文件中通過實現導入導入模塊使用統一的模塊化規范,可以提高代碼的可讀性,更易于維護。類操作先實戰創建一個類在中創建實例中的類能讓我們可以用更簡明的語法實現繼承,也使代碼的可讀性變得更高。 上一篇通過TodoList的練習,目的是為了讓大家理解ES6中各種新特性的實際用途。 最好的學習方法就是實踐,所以這節課結合實際項目,來更好的理解和掌握...
閱讀 3499·2023-04-25 15:52
閱讀 581·2021-11-19 09:40
閱讀 2573·2021-09-26 09:47
閱讀 1023·2021-09-22 15:17
閱讀 3548·2021-08-13 13:25
閱讀 2200·2019-08-30 15:56
閱讀 3460·2019-08-30 13:56
閱讀 2095·2019-08-30 11:27