淺析Redux數據流

原文地址:https://github.com/YutHelloWo...react

redux

-- React Redux 數據流git

經過這張流程圖,咱們能夠更好的理解Redux和React直接數據如何流通,關係如何映射。github

讓咱們一步步來了解圖中的各個概念。redux

action & actionCreator

action creator 就是函數而已,負責構建一個 action (是的,action creator 這個名字已經很明顯了)並返回它。經過幾行簡單的代碼就能夠解釋清楚了!函數

const actionCreator = function () {
  return {
    type : 'AN_ACTION'
  }
}

通常約定 action 是一個擁有 type 屬性的對象。spa

console.log(actionCreator())
//  { type: 'AN_ACTION' }

reducer

Reducer 函數只是一個純函數,它接收應用程序的當前狀態以及發生的 action,而後返回修改後的新狀態(或者有人稱之爲歸併後的狀態)。Reducer 函數是 action 的訂閱者。code

const reducer = function (state = {}, action) {
  console.log('reducer was called with state', state, 'and action', action);

  return state;
}

Store

以上,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' }

combineReducers

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更新。

相關文章
相關標籤/搜索