通惠河边最简单的combineReducers入门与原理

211 阅读1分钟

先看下代码目录

1、入口函数


import React from 'react';
import ReactDOM from 'react-dom';
import Counter from './components/counter';
import Counter2 from './components/counter2';
ReactDOM.render(<div>
    <Counter />
    <Counter2 />
</div>,document.getElementById('root'))

2、两个counter组件

#counter
import React from 'react';
import store from '../store';
import {bindActionCreators} from '../01redux/index';
import * as types from '../store/action-types'

const actions = {
    add: () => ({type: types.add1, val: 1}),
    minus: () => ({type: types.minus1, val: 1})
}
const boundActions = bindActionCreators(actions, store.dispatch)
export default class Counter extends React.Component {
    state = {num: store.getState().counter.num}

    componentDidMount() {
        this.unsubscribe = store.subscribe(() => {
            this.setState({num: store.getState().counter.num})
        })
    }

    componentWillUnmount() {
        this.unsubscribe()
    }

    render() {
        let {num} = this.state
        return <div>
            <p>{num}</p>
            <button onClick={boundActions.add}>add</button>
            <button onClick={boundActions.minus}>minus</button>
        </div>
    }
}

#counter2
import React from 'react';
import store from '../store';
import {bindActionCreators} from '../01redux/index';
import * as types from '../store/action-types'

const actions = {
    add: () => ({type: types.add1, val: 1}),
    minus: () => ({type: types.minus1, val: 1})
}
const boundActions = bindActionCreators(actions, store.dispatch)
export default class Counter extends React.Component {
    state = {num: store.getState().counter.num}

    componentDidMount() {
        this.unsubscribe = store.subscribe(() => {
            this.setState({num: store.getState().counter.num})
        })
    }

    componentWillUnmount() {
        this.unsubscribe()
    }

    render() {
        let {num} = this.state
        return <div>
            <p>{num}</p>
            <button onClick={boundActions.add}>add</button>
            <button onClick={boundActions.minus}>minus</button>
        </div>
    }
}

3、action-types

const add1='add1'
const add2='add2'
const minus1='minus1'
const minus2='minus2'
export {
    add1,add2,minus1,minus2
}

4、两个reducer

#reducer
import * as types from '../action-types'

let initialState = {num: 0}

export default function reducer(state = initialState, action) {
    switch (action.type) {
        case types.add1:
            return {num: state.num + action.val}
        case types.minus1:
            return {num: state.num - action.val}
        default:
            return state
    }
}

#reducer2
import * as types from '../action-types'

let initialState = {num: 0}
export default function reducer(state = initialState, action) {
    switch (action.type) {
        case types.add2:
            return {num: state.num + action.val}
        case types.minus2:
            return {num: state.num - action.val}
        default:
            return state
    }
}

5、合并reducer生成store并返回

import  {combineReducers,createStore} from 'redux';
import counter from './reducer/counter';
import counter2 from './reducer/counter2';

let reducers=combineReducers({counter,counter2})
export default createStore(reducers);

6、此时即可使用两个计数器互不影响,看得出来本篇的核心是combineReducers

//于是我们自己实现下该函数:本质上接受一个对象并返回json形式的reduces合集,如下
function combineReducers(reducers={}) {
    return function (initialState,actions) {
        let newState={}
        for (const reducersKey in reducers) {
            newState[reducersKey]=reducers[reducersKey](initialState[reducersKey],actions)
        }
        return newState
    }
}