react實踐之 redux react-redux

關於redux的介紹推薦去看阮一峯老師的系列文章,可是我這裏要先對redux的store和state作一些額外的說明react

首先 對於單頁應用程序來講全局只有一個store,state固然也只有一個,若是是多頁應用,通常每一頁對於一個store和一個state,固然,我這裏的頁是指入口。redux

下面將說明項目裏如何使用react redux react-redux數組

說明,爲何要同時使用react-redex 由於它能簡化你的操做,而且對合理和規範有必定的強制做用
若是要使用這三個東西會涉及到 action component container reducer store dispatch connectapp


整個流程是這樣的
1 咱們給 component組件 傳入一個函數,假如這個函數是在用戶的點擊事件中出發的dom

2 當用戶 點擊的時候會觸發這個函數 在這個函數裏 會調用dispatch發送一個actionide

3 你定義的reduer函數會根據 發送的那個action來計算點擊事件對應的state函數

4 這個全局的state變化後會更新對應的組件 這個對應的組件就是致使dispatch(action)的那個組件也就是你註冊點擊事件的那個組件所對應的容器包裹着的組件會總體被更新,也 就是說這個容器包裹的組件關心當前這種結構的state,其它的容器包裹的組件是不會被更新的this

代碼實踐及詳細說明
假如咱們已經有了一個組件 MyClickComponent 咱們須要用一個容器去包裹它,而且給它傳入咱們的那個在點擊時會調用而且發送action的方法spa

1 這裏是container 文件code

import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'

/*經過定義這個方法容器組件會將state的成員傳遞給
MyClickComponent 能夠在MyClickComponent中經過
this.props.info 引用到*/

function mapStateToProps(state) {
  return {
    info: state.info
  }
}

在這裏咱們要將那個點擊時的回調函數經過容器傳遞給 MyClickComponent
這個子組件因爲咱們用了react-redux 因此這個容器咱們不會去顯示的像定
義組件那樣去定義,咱們是經過react-redux 的connect來生成的

這裏的callbackList 是一個數組 這個數組裏的方法是咱們要傳遞給子組件的
而且沒一個方法裏面都會調用dispatch來發送 action 這些回調方法咱們在組
件中經過 this.props均可以引用到,

而後將它們註冊到點擊事件,鼠標事件,鍵盤事件等等的回調中去,這樣用戶
的操做就會發送一個action致使state更新,回過頭來刷新組件我能應當明白
mapStateToProps和mapDispatchToProps是在容器中調用的全部容器會將全局
的state和dispatch傳遞給這兩個方法 至於怎麼傳 你不須要關心,你只須要
關心怎麼用

咱們看到有個 bindActionCreators ,這個方法接收兩個參數,
一個是裝了咱們要傳遞給組件的方法的數組,
一個是dispatch 經過調用這個方法到底作了什麼事
這個函數會遍歷callbackList 將 它裏面的每個函數 例如 有個click
click=dispatch(click.apply(undefined, arguments)最終生成了包裝後的click 全部的函數都會被包裝
這裏我把第一個參數叫作callbackList,不少人喜歡叫作actionCreators 從表面意思來看好像這個函數建立了
action 沒錯,咱們剛開始就說了,在那個回調函數中會調用 dispach(action) 那這個action是哪裏來的如何建立的呢

function mapDispatchToProps(dispatch) {
  return bindActionCreators(callbackList, dispatch)
}

建立了咱們一直在說的那個容器 第二個框號裏的MyClickComponent 是咱們被包裹的那個組件

const Container = connect(mapStateToProps, mapDispatchToProps)(MyClickComponent)
    export Container

2 這裏是action 文件

export const UPDATE='UPDATE'
function actionCreater(info) {
    //return的那個對象就是咱們的action
    return {
        type: UPDATE,
        info: info
    }
}

export function click() {
    return (dispatch, getState) => {
        setTimeout(() => {
            //這裏能夠向後臺去請求須要的 info 數據
            //我用setTimeout模擬請求到的數據用來作action的最重要的一部分數據
            //這裏的info咱們能夠在組件中經過this.props.info獲得
            //由此就能明白爲何這個函數也叫actionCreator由於它確實間接的建立了action
            dispatch(actionCreater(info))
        }, 20)
    }
}

3 這裏是reducer文件

//payload 是咱們用來生成state的數據
//payload 能夠是對應函數,任意你想要的東西
function clickReducer(payload = 'click', action) {
    switch (action.type) {
        case UPDATE:
            return action.info
        default:
            return payload
    }
}
//因爲能夠有多個reducer 因此 用combineReducers
//注意這裏決定了你最終的state的結構 例如
//    const rootReducer = combineReducers({
//      info:clickReducer,
//      info2:reducer2
//    })
//  對應的  state {
//                info:clickReducer,
//                info2:reducer2
//            }
//
const rootReducer = combineReducers({
  info:clickReducer
})

export default rootReducer
//整個應用只有一個reducer 包含了全部的產生state的邏輯

4 這裏是 store 文件

export function createStore(initialState) {
  const store = applyMiddleware(thunk)(createStore)(rootReducer, initialState)
  return store
}

applyMiddleware有三個框號就是柯里化,好高端 就是先調用applyMiddleware(thunk)返回一個函數
這個函數須要 createStore 參數 而後又返回一個函數又須要 initialState參數
這裏只是倒出了一個建立store的方法,並無建立store

5 這裏是 entry文件

import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
const store = createStore()
render(
    <Provider store={store}>
        <Container/>
    </Provider>,
    document.getElementById('root')
)

這樣整個流程就結束,沒錯就這麼簡單,這樣咱們就能夠在組件MyClickComponent中隨意的註冊click事件
而且隨意的使用 info ,一旦註冊了click,只要用戶有相應的操做就會更新state,同時你會獲得新的info
值,同時會走一個react 存在的生命週期,有必要的時候會刷新頁面

接下來我還會有幾篇關於react技術棧的文章

下一次 詳細分析 combineReducers connect applyMiddleware bindActionCreators compose這幾個函數的原理,有須要的同志關注

相關文章
相關標籤/搜索