Redux之深刻理解Store、Action、Reducer

前面有一篇文章比較詳細的介紹了redux,那麼這篇文章主要是對redux中的幾個角色進行深刻的理解。主要有如下幾個部分:vue

  • store
  • action
  • reducer
  • combineReducers
  • bindActionCreators

理解Store

const store = createStore(reducer)react

store中經常使用的三個方法:web

  1. getState()-獲取state對象
  2. dispatch(action)-當從UI上改變某個狀態的時候,須要dispatch一個action
  3. subscribe(listener)-通知UI,作出對應的改變

理解Action

一個Action實際上是描述行爲的數據結構,如一個ToDoList的應用結構。好比要增長一個ToDoItem,用action去描述:vuex

{
  type:'ADD_TODO',
  text:'Build my first Redux App'
}

理解Reducer

那麼怎麼去更新以前的ToDoList,這時候就須要reduer,reducer實際上是一個純函數(其輸出結果只依賴於傳入的參數)。這個函數通常接受兩個參數:redux

  • state-以前的狀態
  • action數據結構

    function todoApp(state=initialState,action){
        switch(action.type){
           case ADD_TODO:
               return Object.assign({},state,{
                 todos:[
                   ...state.todos,
                   {
                       text:action.text,
                       completed:false
                   }
                 ]
              })
           break;
           default:
               return state
        }
     }

理解combineReducers

咱們知道一個reducer其實就是一個函數,若是你的應用中有多個reducer的話,那麼如何將它們組合起來一塊兒使用?這時候就須要combineReducers這個工具函數了。這個函數能夠接受多個reducer做爲參數,最終造成的是一個封裝後的函數。這個封裝後的函數其實也是一個reducer.函數

import {combineReducers} from 'redux'
import todoApp from './todoApp'
import counter from './counter'

export default combineReducers({
    todoApp,
    counter
})

理解bindActionCreators

這個方法其實也是一個工具函數,能夠幫助咱們去使用action工具

function addTodoWithDispatch(text){
    const action = {
        type:ADD_TODO,
        text
    }
    dispatch(action)
}

以上代碼表示定義action的同時進行dispatch的操做ui

dispatch(addTodo(text))
dispatch(completeTodo(text))

那麼使用bindCationCreators來實現以上的操做就簡便不少,如:spa

const boundAddTodo = text => dispatch(addTodo(text))
const boundCompleteTodo = text => dispatch(completeTodo(text))

最終演示代碼以下:

PureRedux.js

import React from 'react'
import {createStore,bindActionCreators,combineReducers} from 'redux'
function run(){
    // init state
    const initialState = {
        count:0
    }

    //create a reducer
    const counter = (state=initialState,action) => {
        switch(action.type){
            case 'PLUS_ONE':
                return {count:state.count+1};
            case 'MINUS_ONE':
                return {count:state.count-1};
            case 'CUSTOM_COUNT':
                return{
                    count:state.count+action.payload.count
                }     
            default:
                break;       
        }
        return state
    }

    const todoApp = (state={}) => state

    //create store
    const store = createStore(combineReducers({
        counter,
        todoApp
    }));

    //cation creator
    function flusOne(){
        return {type:'PLUS_ONE'}
    }

    function minusOne(){
        return {type:'MINUS_ONE'}
    }

    function customCount(count){
        return {type:'CUSTOM_COUNT',payload:{count}}
    }

    flusOne = bindActionCreators(flusOne,store.dispatch)

    store.subscribe(() => console.log(store.getState()))
    // store.dispatch(flusOne());
    flusOne();
    store.dispatch(minusOne())
    store.dispatch(customCount(5))
}

export default () => (
    <div>
        <button onClick={run}>
            Run
        </button>
        <p>
            --請打開控制檯查看運行結果
        </p>
    </div>
)

App.js

import React from 'react'
import PureRedux from './PureRedux'
class App extends React.Component{

    render(){
        return(
            <div>
                <PureRedux></PureRedux>
            </div>
        )
    }
}

export default App

總結

  • 對於應用的全局狀態進行管理,是在進行web開發中很重要的必定,這樣可讓咱們統一去作維護,像VueJs的vuex,能夠結合React使用的Redux等。
  • 在傳統的MVC模式中,可能一個view對應多個model,或是多個view對應一個model,當應用變得複雜的時候,這樣的管理是很亂其不易維護的,而redux則是利用一個外界倉庫(store),來對應用的狀態進行統一管理(單向數據流),當用戶操做UI想改變某個state的時候,必須經過dispatch(action)去操做,最後經過store對象的subscribe方法去進行UI的更新。
  • 當一個應用中有多個reducer(純函數,用來根據action改變state)的時候,能夠經過redux中的combineReducers來對多個reducer進行封裝管理。
相關文章
相關標籤/搜索