使用combineReducers()可以提供与单个reducer不同的运行时结果

时间:2018-06-01 14:15:50

标签: javascript reactjs typescript redux

我正在尝试从具有初始状态的根减速器初始化基本存储。

我的根减速机

import Entity from "../api/Entity";
import { UPDATE_GROUPING } from "../constants/action-types";
import IAction from "../interfaces/IAction";
import IStoreState from "../interfaces/IStoreState";

const initialState:IStoreState = {
  callsInProgress: false,
  groupingOptions: ["Strategy", "User", "Date"],
  groupingType: "Strategy",
  numberOfCalls: 2,
  items: [new Entity()],
};


const rootReducer = (state = initialState, action: IAction<object>) => {  
  switch (action.type) {
    case UPDATE_GROUPING:
      return { ...state, groupingType: action.payload};
    default:
      return state;
  }  
};

export default rootReducer;

当我使用rootreducer创建商店时,如下所示

import { createStore } from 'redux';
import rootreducer  from '../reducers/rootreducer';

const store = createStore(rootreducer);
export default store;

有效。 React组件初始化为groupingType,groupingOptions等的正确状态。

但是如果我尝试使用combineReducers()方法 - 即使只有这个单根减速器(应该是相同的),那么当我的组件加载时,它们没有传递任何初始状态。

import { createStore } from 'redux';
import reducers  from '../reducers';

const store = createStore(reducers);
export default store;

我在reducers文件夹中的index.ts,它返回一个combineReducers()调用(不起作用的那个)

import {combineReducers} from 'redux';
import rootreducer from './rootreducer';

// main reducers
export default combineReducers({
  rootreducer
});

最后我的组件挂钩到redux并且应该从redux商店导入状态

import updateGroupingType from "./actions/uiactions";
import './App.css';
import * as React from 'react';
import { connect } from 'react-redux';
import IStoreState from './interfaces/IStoreState';

interface IGroupingProps {
    groupingOptions? : string[],
    groupingType? : string,
    updateGroupingAction? : any
  }

class GroupingSelector extends React.Component<IGroupingProps, {}> {

    constructor(props: IGroupingProps) {
        super(props);

        this.onGroupingChange = this.onGroupingChange.bind(this);
      }

      public render() {
            if (this.props.groupingOptions == null)
            {
                return null;
            }

                return (
            <div className="Grouping-selector">
                <div className="Horizontal-panel-right Grouping-search-combo">
                    <select onChange={this.onGroupingChange}>
                        {this.props.groupingOptions.map((name, index)=> 
                            <option key={index}>{name}</option>
                        )}
                    </select>
                </div>
                <div className="Content Horizontal-panel-right">
                    Group by
                </div>            
            </div>);
        }

    private onGroupingChange(e: any) {
          const { value } = e.target;
          this.props.updateGroupingAction(value);
      }    
}

const mapStateToProps:any = (state: IStoreState) => {
    return {
        groupingOptions: state.groupingOptions,
        groupingType: state.groupingType,
    };
  }    

const mapDispatchToProps = (dispatch:any) => {
    return {
        updateGroupingAction: (groupingType:string) => dispatch(updateGroupingType(groupingType))
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(GroupingSelector);

为什么我对combineReducers的使用与我使用单根rootreducer的方式不同?

2 个答案:

答案 0 :(得分:1)

From the doc

combineReducers辅助函数将一个值不同的对象减少函数转换为一个可以传递给createStore的简化函数。

生成的reducer调用每个子reducer,并将其结果收集到一个状态对象中。 combineReducers()生成的状态命名空间,每个reducer的状态在其键下传递给combineReducers()

当您使用rootReducer作为combineReducers内部的键时,它将创建一个形状为

的状态

{“rootReducer”:YOUR_PREVIOUS_STATE}

只有当每个键都有不同的reducer

时,才应使用combineReducers

答案 1 :(得分:1)

你的root reducer应该是键值对,比如

export default combineReducers({
  home:homeReducer
});

因此,在您的组件mapStateToProps()中,您将能够访问这些值,

const mapStateToProps = (state: any) => {
  return {
    users: state.home
  };
};