redux裏面的概念不少,有Action、ActionCreator、reducer、store、middleware、Provider、Connect……概念不理解,就是眉毛鬍子一把抓,弄不出頭緒。redux的概念,經過一張圖你們就一目瞭然了。git
這張圖大體能夠歸納redux的整個流程。從圖中咱們能夠看出,Action是數據流動的開始,Reducer負責業務邏輯處理,store是整個流程的中軸。github
一、你從哪裏來?——談談actions的起源ajax
redux裏的action和flux裏的action大致上一致,不一樣的是設計理念的差異。flux裏的action是以函數的形式,但在redux裏,action被設計成普通的js對象。編程
{
type: 'ADD_TODO',
text: 'Build my first Redux app'
}
這就是一個最基本的action,必須注意的是,type是action必須的一個key值,是action的惟一標識。其它的key可使任意像傳遞的數據結構。
可是actions到底表明什麼?
actions表明着數據來源的萃取。咱們的view界面須要不少數據結構,如ajax返回的數據、路由狀態跟蹤、UI狀態等。。。關鍵的是這些數據都是動態流動的,既然流動,就要有入口、有方向。actions就是表明數據流動的開始,攜帶的key值中,type表明發生了什麼事情,其它的就是須要流動的數據結構。
概括起來,actions是數據從應用傳到store的有效載荷,是store惟一的數據來源。
那麼如何產生一個action,這就是又有一個概念actionCreator:redux
function addTodo(text) {數據結構
return { type: ADD_TODO, text };
}
actionCreator其實是一個返回action值的函數而已。這樣,只需把 action 生成器的結果傳給 dispatch() 方法便可實例化 dispatch。app
dispatch(addTodo(text));
二、條條大路通哪裏?——看看reducer的神奇async
action表示發生了什麼事情,代表了有事情發生,確定會對應用的數據產生影響。咱們知道,React組件內的數據都是以state的形式存在的,state表明着數據結構。那麼就要問了,action的發生到底會對state產生什麼影響。這就是reducer的做用了。
reducer 實際上是一個函數, 接收舊的 state 和 action, 返回新的 state。ide
(previousState, action) => newState
這種設計來源於函數式編程思想,簡單,易懂,沒有反作用。函數式編程
function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, { visibilityFilter: action.filter });
default:
return state;
}
}
能夠看出,業務邏輯部分都是在reducer裏處理。這就涉及一個問題,一個應用裏有不少邏輯部分,都放在一個reducer裏面會形成很是的臃腫。實際過程當中,把業務進行分拆,而後經過combineReducer函數合併成一個reducer。詳細能夠看這裏:
https://github.com/rackt/redux/blob/mast...
切記,在reducer不要改變舊的state值。
三、看看你是誰?——揭開store的面紗
首先咱們看文檔裏怎麼描述的:
The Store is the object that brings themtogether.(them指的是action和reducer)
It’s important to note that you’ll only have a single store in a Redux application.
這就說明,Store負責把reducer和action結合的做用。store怎麼建立?通常是經過下面的代碼:
const store = createStore(reducer);
這個createStore又是什麼函數,咱們看看createStore.js源碼:
import isPlainObject from './utils/isPlainObject'; export var ActionTypes = { INIT: '@@redux/INIT' }; export default function createStore(reducer, initialState) { if (typeof reducer !== 'function') { throw new Error('Expected the reducer to be a function.'); } var currentReducer = reducer; var currentState = initialState; var listeners = []; var isDispatching = false; function getState() { return currentState; } function subscribe(listener) { listeners.push(listener); return function unsubscribe() { var index = listeners.indexOf(listener); listeners.splice(index, 1); }; } function dispatch(action) { if (!isPlainObject(action)) { throw new Error( 'Actions must be plain objects. ' + 'Use custom middleware for async actions.' ); } if (typeof action.type === 'undefined') { throw new Error( 'Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?' ); } if (isDispatching) { throw new Error('Reducers may not dispatch actions.'); } try { isDispatching = true; currentState = currentReducer(currentState, action); } finally { isDispatching = false; } listeners.slice().forEach(listener => listener()); return action; } function replaceReducer(nextReducer) { currentReducer = nextReducer; dispatch({ type: ActionTypes.INIT }); } dispatch({ type: ActionTypes.INIT }); return { dispatch, subscribe, getState, replaceReducer }; }
咱們能夠看到createStore返回的是一個對象,該對象有四種方法,分別是:
dispatch, subscribe, getState, replaceReducer
能夠看出redux裏的store有點像flux裏的dispatcher的做用,產生action能夠經過store.dispatch發送出去,想監聽狀態能夠經過store.subscribe訂閱。
值得注意的是,程序初始化的時候,redux會發送一個類型爲@@redux/INIT的action,來初始化state。
以上就是我對redux流程前半部分的理解,請批評指正。