一剥扣、概述
Flux和Redux 是React生態(tài)中重要的組成部分细燎,個人覺得缝呕,它們核心功能就是將頁面 和 數(shù)據(jù)+邏輯 解耦澳窑,將數(shù)據(jù)+邏輯 進(jìn)一步抽象組件化。
二供常、Flux
Flux是一套架構(gòu)模式摊聋,而不是代碼框架。所謂的架構(gòu)模式栈暇,是一套方法論麻裁,指導(dǎo)系統(tǒng)如何更好搭建。例如模塊如何劃分?模塊間如何通信悲立?Web開發(fā)中的MVC模式鹿寨,其實就是架構(gòu)模式。
1薪夕、四大核心部分
- dispatcher:負(fù)責(zé)兩件事脚草,一是分發(fā)和處理Action,二是維護(hù)Store原献。
- Store:數(shù)據(jù)和邏輯部分馏慨。
- views:頁面-React 組件,從 Store 獲取狀態(tài)(數(shù)據(jù))姑隅,綁定事件處理写隶。
- actions:交互封裝為action,提交給Store處理讲仰。
2慕趴、架構(gòu)設(shè)計
- 【單向數(shù)據(jù)流】:
Action -> Dispatcher -> Store -> View
- 頁面交互數(shù)據(jù)流,如用戶點(diǎn)擊按鈕:
View -> Create Action -> Dispatcher(由此進(jìn)入【單向數(shù)據(jù)流】)
Flux參考
具體的Demo和用法參考一下教程鄙陡,很詳細(xì)了~
ReacFlux教程
三冕房、Redux
1、什么Redux趁矾?
Redux 是 JavaScript 狀態(tài)容器耙册, 提供可預(yù)測化的狀態(tài)管理。那什么是可以預(yù)測化毫捣,我的理解就是根據(jù)一個固定的輸入详拙,必然會得到一個固定的結(jié)果。
Redux是進(jìn)化Flux蔓同,它是在Flux架構(gòu)模式指導(dǎo)下生成的代碼框架饶辙,也進(jìn)一步進(jìn)行架構(gòu)約束設(shè)計。
- Redux 的適用場景:多交互牌柄、多數(shù)據(jù)源畸悬。
2侧甫、Redux的核心思想
借用阮一峰大神的話:Redux 的設(shè)計思想很簡單珊佣,就兩句話。
- 1披粟、Web 應(yīng)用是一個狀態(tài)機(jī)咒锻,視圖與狀態(tài)是一一對應(yīng)的。
- 2守屉、所有的狀態(tài)惑艇,保存在一個對象里面。
3、Redux的架構(gòu)約束
對于 Store 的約束
一個應(yīng)用對應(yīng)一個全局Store滨巴,可用單例模式來實現(xiàn)思灌。
Store只有store.getState()
、store.dispatch()
恭取、store.subscribe()
三個方法泰偿。
初始化需要綁定reducer函數(shù)
,調(diào)用store.dispatch方法
會自動觸發(fā)reducer函數(shù)
的執(zhí)行蜈垮。對于 State 的約束
一個 State 對應(yīng)一個應(yīng)用耗跛,整個應(yīng)用只有一個 State 對象,包含所有數(shù)據(jù)攒发。整個應(yīng)用只維護(hù)成一個樹形state调塌。
State對象是只讀的,最好把 State對象設(shè)成只讀惠猿,不可變羔砾,即聲明為
const`。state的只能通過action觸發(fā)生成新的state偶妖。
如果想得到某個時點(diǎn)的數(shù)據(jù)蜒茄,就要對 Store 生成快照。這種時點(diǎn)的數(shù)據(jù)集合餐屎,就叫做 State檀葛。對于 Actions 的約束
Redux簡化了Action,它就是一個單純的包含{ type, payload, error, meta }
的對象腹缩;type
是一個常量用來標(biāo)示動作類型屿聋;payload
是這個動作攜帶的數(shù)據(jù)。其中的type
屬性是必須的藏鹊,表示 Action 的名稱润讥,其他屬性可以自由設(shè)置,社區(qū)有一個規(guī)范可以參考盘寡。不允許擴(kuò)展其他自定義屬性字段楚殿。
-
引入 Reducer :作用是保證State不可變,處理State數(shù)據(jù)竿痰。
Store 收到 Action 以后脆粥,必須給出一個新的 State,這樣 View 才會發(fā)生變化影涉。這種 State 的計算過程就叫做 Reducer变隔。因此,
reducer函數(shù)
必須是一個純函數(shù)蟹倾。也就是說匣缘,只要是同樣的輸入猖闪,必定得到同樣的輸出。
也就是說肌厨,一個reducer函數(shù)
會接受初始狀態(tài)originalState
和action
兩個參數(shù)培慌,返回一個新的state:(originalState, action) => newState
。
4柑爸、Redux的工作流
- 單向數(shù)據(jù)流:
store.dispatch(action) -> reducer(state, action) -> store.getState()
2055834352-59daefda643b8_fix732.png
5检柬、Redux的簡單Demo
- 實現(xiàn)Reducer
// state只讀
const defaultState = 0;
const reducer = (state = defaultState, action) => {
switch (action.type) {
case 'ADD':
return state + action.payload;
default:
return state;
}
};
- 初始化Store,需要綁定reducer函數(shù)
import { createStore } from 'redux';
var store = createStore(reducer)
- 獲取狀態(tài)State
store.getState()
- 監(jiān)聽狀態(tài)State
// 注冊
let unsubscribe = store.subscribe(() =>
console.log(store.getState())
);
// 銷毀
unsubscribe();
- 分發(fā)Actions
const action = {
type: 'ADD',
payload: 'Learn Redux'
};
store.dispatch(action);
5竖配、Redux讓開發(fā)者專注于數(shù)據(jù)流的處理何址。
Redux框架約束Store
,封裝了 訂閱store.subscribe
和 分發(fā)store.dispatch
的行為进胯;封裝了Action
的動作用爪;抽象定義了State
對象⌒哺洌框架定義一整套完整的工作流程偎血,開發(fā)者只需要關(guān)注于React組件頁面,專注于相關(guān)業(yè)務(wù)數(shù)據(jù)流的設(shè)計和處理盯漂。
框架提供以下方式支持?jǐn)?shù)據(jù)多樣性颇玷。
通過Actions實現(xiàn)數(shù)據(jù)多樣性:通過action的屬性字段(
payload、errer就缆、meta
)傳遞用戶自定義數(shù)據(jù)帖渠。通過State實現(xiàn)數(shù)據(jù)多樣性:state對象只讀,但是可以有多個的屬性竭宰。
const initialState={
a: data 1,
b: data 2,
c: data 3
}
我們可以把 Reducer 函數(shù)拆分空郊,不同的函數(shù)負(fù)責(zé)處理不同屬性,最終把它們合并成一個大的 Reducer 即可切揭。Redux 提供了一個 combineReducers
方法狞甚,用于 Reducer 的拆分。你只要定義各個子 Reducer 函數(shù)廓旬,然后用這個方法哼审,將它們合成一個大的 Reducer。
const reducer = combineReducers({
a: doSomethingWithA,
b: processB,
c: c
})
// 等同于
function reducer(state = {}, action) {
return {
a: doSomethingWithA(state.a, action),
b: processB(state.b, action),
c: c(state.c, action)
}
}
四孕豹、中間件技術(shù)涩盾,讓Redux支持異步
Redux從生成action,dispatch action巩步,生成新的state旁赊,頁面更新桦踊,這一工作流是同步的椅野。
實際開發(fā)中,需要異步的場景,redux如何支持呢竟闪? 這需要用到中間件技術(shù)离福。
什么是中間件?
通俗理解炼蛤,就是額外增加一層中間層妖爷,這一層單獨(dú)處理一組通用的邏輯行為,例如打日志理朋、異步操作等絮识。-
Redux原生方法
applyMiddlewares()
它是 Redux 的原生方法,作用是將所有中間件組成一個數(shù)組嗽上,依次執(zhí)行次舌。源碼實現(xiàn)原理是將入?yún)⒌乃兄虚g件被放進(jìn)了一個數(shù)組chain
,然后嵌套執(zhí)行兽愤,最后執(zhí)行store.dispatch
彼念。
bg2016092002.jpg 異步中間件
redux-thunk
、redux-promise
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducers';
// Note: this API requires redux@>=3.1.0
const store = createStore(
reducer,
applyMiddleware(thunk)
);
Redux參考
阮一峰:Redux 入門教程(一):基本用法
阮一峰:Redux 入門教程(二):中間件與異步操作
Redux入門教程(快速上手)
Redux教程