原文地址:https://github.com/YutHelloWo...react
-- React Redux 數據流git
經過這張流程圖,咱們能夠更好的理解Redux和React直接數據如何流通,關係如何映射。github
讓咱們一步步來了解圖中的各個概念。redux
action creator 就是函數而已,負責構建一個 action (是的,action creator 這個名字已經很明顯了)並返回它。經過幾行簡單的代碼就能夠解釋清楚了!函數
const actionCreator = function () { return { type : 'AN_ACTION' } }
通常約定 action 是一個擁有 type 屬性的對象。spa
console.log(actionCreator()) // { type: 'AN_ACTION' }
Reducer 函數只是一個純函數,它接收應用程序的當前狀態以及發生的 action,而後返回修改後的新狀態(或者有人稱之爲歸併後的狀態)。Reducer 函數是 action 的訂閱者。code
const reducer = function (state = {}, action) { console.log('reducer was called with state', state, 'and action', action); return state; }
以上,action描述「發生了什麼」,而reducer根據action來更新state。可是他們二者之間是如何關聯的呢?對象
不用擔憂,Redux 會幫你把action和reducer鏈接起來。blog
咱們把 Redux實例稱爲 store
並用如下方式建立:事件
import { createStore } from 'redux' const store_0 = createStore(() => {})
注意:在createStore時,須要給它傳入一個 reducer 函數。
每當一個action發生時,Redux都能調用這個函數。往 createStore 傳 Reducer 的過程就是給 Redux綁定 action處理函數(也就是Reducer)的過程。
接下來,試着在 Reducer 中打印一些 log
const reducer = function (...args) { console.log('Reducer was called with args', args) } const store_1 = createStore(reducer) // 輸出:Reducer was called with args [ undefined, { type: '@@redux/INIT' } ]
咱們沒有dispatch(分發)任何action,可是reducer被調用了!這是因爲初始化應用state的時候,Redux dispatch 了一個初始化的 action ({ type: '@@redux/INIT' })
。reducer的入參爲(state, action)
。state尚未被初始化,天然爲undefined
。
如何讀取store中的state?
Redux爲咱們提供了store.getState()
方法。
import { createStore } from 'redux' const reducer_2 = function (state = {}, action) { console.log('reducer_2 was called with state', state, 'and action', action) return state; } const store_2 = createStore(reducer_2) // 輸出: reducer_2 was called with state {} and action { type: '@@redux/INIT' } console.log('store_2 state after initialization:', store_2.getState()) // 輸出: store_2 state after initialization: {}
如何dispatch action?
咱們須要使用store.dispatch(action)
方法。
// 接以上代碼 const anAction = { type : 'AN_ACTION' } store_2.dispatch(anAction); // 輸出:reducer_2 was called with state {} and action { type: 'AN_ACTION' }
combineReducer
用於合併Reducers,而且合併對應的State。
const userReducer = function (state = {}, action) { console.log('userReducer was called with state', state, 'and action', action) switch (action.type) { // etc. default: return state; } } const itemsReducer = function (state = [], action) { console.log('itemsReducer was called with state', state, 'and action', action) switch (action.type) { // etc. default: return state; } } import { createStore, combineReducers } from 'redux' const reducer = combineReducers({ user : userReducer, items : itemsReducer }) // 輸出: // userReducer was called with state {} and action { type: '@@redux/INIT' } // userReducer was called with state {} and action { type: '@@redux/PROBE_UNKNOWN_ACTION_9.r.k.r.i.c.n.m.i' } // itemsReducer was called with state [] and action { type: '@@redux/INIT' } // itemsReducer was called with state [] and action { type: '@@redux/PROBE_UNKNOWN_ACTION_4.f.i.z.l.3.7.s.y.v.i' } var store_0 = createStore(reducer) // 輸出: // userReducer was called with state {} and action { type: '@@redux/INIT' } // itemsReducer was called with state [] and action { type: '@@redux/INIT' } console.log('store_0 state after initialization:', store_0.getState()) // 輸出: // store_0 state after initialization: { user: {}, items: [] }
View組件經過click等事件,dispatch一個(actionCreator返回的)action,經過Store把當前狀態state和action傳遞給訂閱者reducer函數,reducer返回一個新的狀態存儲在Store中,Store又把新的State傳遞給View組件觸發組件更新。
爲了將Redux和React聯繫到一塊兒。就須要用到React-Redux
這個庫。
import { connect } from 'react-redux' const containerComponent = connect(mapStateToProps, mapDispatchToProps)(presentationalComponent)
簡單來講,mapStateToProps和mapDispatchToProps就是分別把Redux的state,和dispatch(action)映射到React組件中做爲props。connect
將展現組件(presentationalComponent)封裝成高階的容器組件(containerComponent)。state的更新意味着props更新。