React+Redux 這種開發(fā)模式在公司跌跌撞撞的使用已經(jīng)有五個月了。對這種開發(fā)模式進行一個MVC的總結(jié)算也是跟以前的知識結(jié)構(gòu)做一個對接朝刊。
本文會按照當前項目中碰到的問題以及想澄清的一些概念來整理镊掖。
- 什么是MVC浴井?為什么要MVC钦讳?
- React中的幾個概念是干什么的鲫剿?
- Redux中的幾個概念是干什么的银室?
- React+Redux的MVC分層是什么樣的涂佃?
1. 什么是MVC?我們?yōu)槭裁匆狹VC蜈敢?
Model(模型)是應用程序中用于處理應用程序數(shù)據(jù)和邏輯的部分辜荠。“模型”不依賴“視圖”和“控制器”抓狭,也就是說伯病,模型不關(guān)心它會被如何顯示或是如何被操作。
Model層主要有兩個部分:1. DBObj定義數(shù)據(jù)庫中對應的數(shù)據(jù)模型否过;2. 是邏輯的處理包括直接對數(shù)據(jù)庫和網(wǎng)絡數(shù)據(jù)的訪問處理午笛;
在我們的程序里面把這層也叫做業(yè)務層處理層。跟React和Redux的代碼沒有任何關(guān)系的一層苗桂。View(視圖)是應用程序中處理數(shù)據(jù)顯示的部分药磺。視圖層主要包括二個部分:1.視圖層顯示及交互邏輯;2.視圖層的數(shù)據(jù)結(jié)構(gòu)ViewObj煤伟, 包括React中的props和stats癌佩;
Controller(控制器)是響應視圖層的事件和被動調(diào)用的事件(WebSocket發(fā)出的事件),根據(jù)不同的事件來組織不同業(yè)務邏輯處理便锨,然后把處理結(jié)果反饋驼卖。而反饋的結(jié)果包括更新界面,更新數(shù)據(jù)模型鸿秆。比如:視圖層的數(shù)據(jù)更新酌畜,即Redux中的reducers。
為什么要用MVC卿叽?主要有三點:
- 使程序更簡單更直觀更容易理解桥胞;
- 在視圖層的開發(fā)恳守,是通過組件搭積木;
- 在控制層的開發(fā)贩虾,是用業(yè)務層的API搭積木催烘。
2. React中的幾個概念是干什么的?
- component
React.createClass方法就用于生成一個component 缎罢,然后像插入普通 HTML 標簽一樣伊群,在網(wǎng)頁中插入這個組件。組件的用法與原生的 HTML 標簽完全一致策精。 - props
組件可以任意加入屬性的舰始,比如 <HelloWord name="Scott"> ,就是 HelloWord 組件加入一個 name 屬性咽袜,值為 Scott丸卷。組件的屬性可以在組件類的 this.props 對象上獲取,比如 name 屬性就可以通過 this.props.name 讀取询刹。
this.props 表示那些一旦定義谜嫉,當前組件就不再改變的特性,但是父組件是可以去修改的凹联。Redux是通過connect把數(shù)據(jù)綁定到React的props來更新界面數(shù)據(jù)的沐兰。 - state
用于用戶互動時當this.state數(shù)據(jù)變化,自動調(diào)用 this.render 方法蔽挠,從而觸發(fā)重新渲染組件僧鲁。this.state 是會隨著用戶互動而產(chǎn)生變化的特性。
用的了Redux后目前我們只用于存放界面顯示控制及狀態(tài)的數(shù)據(jù)象泵。
討論:
- props和state在組件定義和容器定義時使用區(qū)別寞秃?
- component的生命周期中的幾個方法的使用包括:
Mounting(插入到 DOM中)
These methods are called when an instance of a component is being created and inserted into the DOM:
constructor()
componentWillMount()
render()
componentDidMount()
Updating(正在被重新渲染)
An update can be caused by changes to props or state. These methods are called when a component is being re-rendered:
componentWillReceiveProps()
shouldComponentUpdate()
componentWillUpdate()
render()
componentDidUpdate()
Unmounting(已移出真實 DOM)
This method is called when a component is being removed from the DOM:
componentWillUnmount()
3. Redux中的幾個概念是干什么的?
Store 就是保存數(shù)據(jù)的地方偶惠,你可以把它看成一個容器春寿。整個應用只能有一個 Store。Store對象包含所有數(shù)據(jù)
state 就是某個時間點的數(shù)據(jù)忽孽,就要對 Store的快照绑改。
store.dispatch()是 View通過Redux connect中mapDispatchToProps方法發(fā)出 Action 以及被動調(diào)用事件時發(fā)出比如WebSocketServer。
Action函數(shù)是修改state的唯一入口兄一,比如通過connect的mapDispatchToProps方法綁定到視圖層的一個操作厘线,或者是來自WebSocket的一個消息事件;Action函數(shù)最后通過store.dispatch() 發(fā)出的Action對象出革,表示 State 應該要發(fā)生變化了造壮。
通常的做法是在Container層mapDispatchToProps方法中調(diào)用。
Action對象其中的type屬性是必須的,表示 Action 的名稱耳璧。其他屬性可以自由設置成箫。
Reducer 是個純函數(shù),它接受 Action對象 和當前 State 作為參數(shù)旨枯,返回一個新的 State蹬昌。
純函數(shù)是函數(shù)式編程的概念,必須遵守以下一些約束攀隔。
不得改寫參數(shù)
不能調(diào)用系統(tǒng) I/O 的API
不能調(diào)用Date.now()或者Math.random()等不純的方法皂贩,因為每次會得到不一樣的結(jié)果
4. React+Redux的MVC分層是什么樣的?
1.React-Redux庫的組件
React-Redux 庫將所有組件分成兩大類:UI 組件(presentational component)和容器組件(container component)昆汹。
- UI 組件(presentational component)因為不含有狀態(tài)明刷,UI 組件又稱為"純組件",即它純函數(shù)一樣筹煮,純粹由參數(shù)決定它的值。
UI 組件有以下幾個特征居夹。
只負責 UI 的呈現(xiàn)败潦,不帶有任何業(yè)務邏輯
沒有狀態(tài)(即不使用this.state這個變量)
所有數(shù)據(jù)都由參數(shù)(this.props)提供
不使用任何 Redux 的 API
- 容器組件(container component)使用connect生成的
負責管理數(shù)據(jù)和業(yè)務邏輯,不負責 UI 的呈現(xiàn)
帶有內(nèi)部狀態(tài)
使用 Redux 的 API
React-Redux 規(guī)定准脂,所有的 UI 組件都由用戶提供劫扒,容器組件則是由 React-Redux 自動生成。也就是說狸膏,用戶負責視覺層沟饥,狀態(tài)管理則是全部交給它。
2.React-Redux庫的connect
React-Redux 提供connect方法湾戳,用于從 UI 組件生成容器組件贤旷。connect的意思,就是將這兩種組件連起來砾脑。
connect方法的完整 API 如下
import { connect } from 'react-redux'
const VisibleTodoList = connect( mapStateToProps, mapDispatchToProps)(TodoList)
connect方法接受兩個參數(shù):mapStateToProps和mapDispatchToProps幼驶。
- mapStateToProps負責輸入邏輯即將state映射到 UI 組件的參數(shù)(props);
- mapDispatchToProps負責輸出邏輯韧衣,即將用戶對 UI 組件的操作映射成 Action盅藻。
3.React+Redux的MVC分層
** 視圖層 ** React(component 、props(包括ViewObj)畅铭、state) (不能調(diào)用Redux的API)
** 控制層 ** Redux connect(輸入邏輯氏淑,輸出邏輯=> Action函數(shù))(Page(由多個組件組成的頁面))->Container
Redux Action函數(shù)(Call->Manager ->DBObj->store.dispatch()) (視圖層和Server都可以調(diào)用Action函數(shù))
Redux Reducer(DBObj->ViewObj->state) (控制顯示數(shù)據(jù)更改)
** 模型層 ** Mangaer層 ->ManagerService -> ORM(DBObj) (不能調(diào)用React和Redux的API)
** 工具包 ** DBOper NetOper