Getting started with Redux 0x103: splitting multiple reducers

Time:2020-10-27

0x001 overview

This chapter talks about more than onereducerHow to deal with it andleduxSupport more than onereducer

0x002 unsealingreducer

import {createStore, combineReducers} from 'redux'

const ACTION_NUM1_INCREMENT = 'ACTION_NUM1_INCREMENT'
const ACTION_NUM2_INCREMENT = 'ACTION_NUM2_INCREMENT'

const num1 = (state = 0, action) => {
    switch (action.type) {
        case ACTION_NUM1_INCREMENT: {
            return ++state
        }
        default: {
            return state
        }
    }
}

const num2 = (state = 0, action) => {
    switch ((action.type)) {
        case ACTION_NUM2_INCREMENT: {
            return ++state
        }
        default: {
            return state
        }
    }
}

const reducer = combineReducers({
    num1: num1,
    num2: num2
})
let store = createStore(reducer)

store.subscribe(() => {
    console.log(store.getState())
})

store.dispatch({type: ACTION_NUM1_INCREMENT})
store.dispatch({type: ACTION_NUM2_INCREMENT})

View browser
Getting started with Redux 0x103: splitting multiple reducers

It’s so simple. The core function is:combineReducers(reducers), set multiplereducerAnd form one. After splitting, what about eachreducerManage one separatelystate

0x002 reconstructionleduxMake it supportivecombineReducers

  • add tocombineReducersAnd modify itstateComputational logic
class Ledux {
    static createStore(reduer) {
        return new Store(reduer)
    }

    static combineReducers(reducers) {
        return reducers
    }
}

class Store {
    constructor(reducer) {
        this.state = this.calculateState(reducer)
        this.callbacks = []
        this.reducer = reducer
    }

    subscribe(callback) {
        this.callbacks.push(callback)
    }

    getState() {
        return this.state
    }

    dispatch(action) {
        this.state = this.calculateState(this.reducer, action)
        this.callbacks.forEach(callback => callback())
    }

    /**
     *A reducer may be an object that passes through combinereducers
     *Therefore, it is necessary to determine whether the reducer is an object
     *If so
     *That means it's a composite reducer
     *Each state needs to be computed in a loop
     *And save it to state as an object
     *If it's not an object and it's a function
     *That shows that this is a single reducer
     *Just calculate it directly
     *Then save it to state
     *
     *@ param reducer single reducer function or object after combinereducers
     * @param action
     * @returns {*}
     */
    calculateState(reducer, action = {}) {
        if (typeof reducer === 'object') {
            return Object.keys(reducer).map((key) => {
                return {
                    [key]: reducer[key](undefined, action)
                }
            }).reduce((pre, current) => {
                return {...pre, ...current}
            })
        } else if (typeof reducer === 'function') {
            return reducer(undefined, action)
        }
    }
}
/**
 *Add several function exports
 *Keep the API consistent with Redux
 *In this way, the function called is not modified
 */
const createStore = Ledux.createStore
const combineReducers = Ledux.combineReducers
export {createStore, combineReducers}
export default Ledux
  • Modify call
//Just modify the introduction of Redux directly
import {createStore, combineReducers} from './ledux'

0x003 summary

nothing

0x004 resource

  • Source code