gif地址javascript
Web 應用是一個狀態機,視圖與狀態是一一對應的。java
全部的狀態,保存在一個對象裏面。react
redux不依賴於reactgit
就是app中數據組成的樹,也是一個普通的js對象。樹的結構根據應用的須要自行決定,官方推薦的方式是分爲三種數據:github
後端提供的應用數據redux
應用狀態數據 (某條數據是否選中)後端
ui組件的數據(彈窗是否打開)app
action是一個描述「發生了什麼」的普通對象
action是咱們開發的應用程序和store間通訊的信息,它就是普通的js對象,結構是自定義的,信息量應儘量小。
例如:ide
{ type: 'ADD_NEWS', text: '這是一條新聞' }
action建立函數函數
function addNews(text) { return { type: 'ADD_NEWS', text } }
reducer是根據action來返回一個全新state的純函數。
function newsReducer(state = initialState, action) { switch (action) { case: 'ADD_NEWS': return [...state, text] break; default: return state; } }
store只是把actions和reducers聯繫在一塊兒的對象,並非傳統意義上象徵數據的東西。
const store = createStore(rootReducer, defaultState)
提供 getState() 方法獲取 state
提供 dispatch(action) 方法更新 state; store.dispatch(addNews('這是一條新聞'))
經過 subscribe(listener) 註冊監聽器
經過 subscribe(listener) 返回的函數註銷監聽器。
component只關注展現層。
container是經過connect方法把redux和展現組件關聯起來的東西。
combineReducers(reducers)
傳入reducers做爲參數, reducers是一個object,如 {news: function() {...}, blogs: function() {...}}
返回一個遍歷執行全部reducers的reducer函數,每一個reducer只處理state中對應本身key的部分.
bindActionCreator
function bindActionCreator(actionCreator, dispatch) { return (...args) => dispatch(actionCreator(...args)) }
bindActionCreators就是把多個actionCreator變成會去執行dispatch的函數,而且返回這個對象。
鏈接 React 組件與 Redux store。鏈接操做不會改變原來的組件類。反而返回一個新的已與 Redux store 鏈接的組件類。
1.mapStateToProps
若是定義該參數,組件將會監聽 Redux store 的變化。任什麼時候候,只要 Redux store 發生改變,mapStateToProps 函數就會被調用。該回調函數必須返回一個純對象,這個對象會與組件的 props 合併。若是你省略了這個參數,你的組件將不會監聽 Redux store。若是指定了該回調函數中的第二個參數 ownProps,則該參數的值爲傳遞到組件的 props,並且只要組件接收到新的 props,mapStateToProps 也會被調用(例如,當 props 接收到來自父組件一個小小的改動,那麼你所使用的 ownProps 參數,mapStateToProps 都會被從新計算)
// 把state上的todos綁定到 組件.props.todos function mapStateToProps(state) { return { todos: state.todos } } export default connect(mapStateToProps)(TodoApp)
2.mapDispatchToProps
(Object or Function): 若是傳遞的是一個對象,那麼每一個定義在該對象的函數都將被看成 Redux action creator,並且這個對象會與 Redux store 綁定在一塊兒,其中所定義的方法名將做爲屬性名,合併到組件的 props 中。若是傳遞的是一個函數,該函數將接收一個 dispatch 函數,而後由你來決定如何返回一個對象,這個對象經過 dispatch 函數與 action creator 以某種方式綁定在一塊兒(提示:你也許會用到 Redux 的輔助函數 bindActionCreators())。若是你省略這個 mapDispatchToProps 參數,默認狀況下,dispatch 會注入到你的組件 props 中。若是指定了該回調函數中第二個參數 ownProps,該參數的值爲傳遞到組件的 props,並且只要組件接收到新 props,mapDispatchToProps 也會被調用。
export function mapDispatchToProps(dispatch) { return bindActionCreators(actionCreators, dispatch); } // 下面兩種方式效果一致 var App = connect(mapStateToProps, actionCreators)(Main); var App = connect(mapStateToProps, mapDispatchToProps)(Main);
包裹Provider讓全部container都能訪問store
store.dispath(action)會執行reducer(currentState, action)並return action。原生的dipatch只支持普通js對象來做爲參數,不然會報錯。
它提供的是位於 action 被髮起以後,到達 reducer 以前的擴展點。(?)
其實就是在dispatch先後作一些額外的事情的一個函數,這個函數就是middleware, 有多個middlewares也就是嵌套地執行這多個函數。
const logger = ({ dispatch, getState }) => next => action => { console.log('dispatching', action) let result = next(action) console.log('next state', getState()) return result } export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { const store = createStore(reducer, preloadedState, enhancer) let dispatch = store.dispatch let chain = [] const middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) } chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } } const middlewares = [logger] const store = createStore( reducer, applyMiddleware(...middlewares) )
經過redux middleware實現支持dispatch一個函數。
function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); }; } const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk;