将reducer包含在CombineReducers中,缺少某些内容

时间:2019-09-18 11:38:43

标签: react-redux

一旦包含我的应用程序开始出现故障,我正尝试在我的应用程序中再添加4个减速器。

出于测试目的,我仅将当前的reducer包含在CombineReducers函数中,并且应用程序也失败了,我认为应用程序不必更改或执行此更改即可。

在这种状态下,应用程序正常工作

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import {Provider} from 'react-redux';
import {BrowserRouter} from 'react-router-dom';

import App from './App/index';
import * as serviceWorker from './serviceWorker';
import { defaultreducer } from './_reducers/default.reducer';
import config from './config';

const store = createStore(reducer);

如果我更改并将reducer包含在CombineReducers函数中,则会导致应用崩溃

import React from 'react';
import ReactDOM from 'react-dom';
import { combineReducers, createStore } from 'redux';
import {Provider} from 'react-redux';
import {BrowserRouter} from 'react-router-dom';

import App from './App/index';
import * as serviceWorker from './serviceWorker';
import { defaultreducer } from './_reducers/default.reducer';
import config from './config';

const root_reducer = combineReducers({
  reducer: defaultreducer
});

const store = createStore(root_reducer);

我的减速器

import * as actionTypes from '../store/actions';
import config from './../config';

const initialState = {
  isOpen: [], //for active default menu
  isTrigger: [], //for active default menu, set blank for horizontal
  ...config,
  isFullScreen: false, // static can't change
}

export function defaultreducer(state = initialState, action) {
    let trigger = [];
    let open = [];

    switch (action.type) {
        case actionTypes.COLLAPSE_MENU:
            return {
                ...state,
                collapseMenu: !state.collapseMenu
            };
        case actionTypes.COLLAPSE_TOGGLE:
            if (action.menu.type === 'sub') {
                open = state.isOpen;
                trigger = state.isTrigger;

                const triggerIndex = trigger.indexOf(action.menu.id);
                if (triggerIndex > -1) {
                    open = open.filter(item => item !== action.menu.id);
                    trigger = trigger.filter(item => item !== action.menu.id);
                }

                if (triggerIndex === -1) {
                    open = [...open, action.menu.id];
                    trigger = [...trigger, action.menu.id];
                }
            } else {
                open = state.isOpen;
                const triggerIndex = (state.isTrigger).indexOf(action.menu.id);
                trigger = (triggerIndex === -1) ? [action.menu.id] : [];
                open = (triggerIndex === -1) ? [action.menu.id] : [];
            }

            return {
                ...state,
                isOpen: open,
                isTrigger: trigger
            };
        case actionTypes.NAV_CONTENT_LEAVE:
            return {
                ...state,
                isOpen: open,
                isTrigger: trigger,
            };
        case actionTypes.NAV_COLLAPSE_LEAVE:
            if (action.menu.type === 'sub') {
                open = state.isOpen;
                trigger = state.isTrigger;

                const triggerIndex = trigger.indexOf(action.menu.id);
                if (triggerIndex > -1) {
                    open = open.filter(item => item !== action.menu.id);
                    trigger = trigger.filter(item => item !== action.menu.id);
                }
                return {
                    ...state,
                    isOpen: open,
                    isTrigger: trigger,
                };
            }
            return {...state};
        case actionTypes.FULL_SCREEN :
            return {
                ...state,
                isFullScreen: !state.isFullScreen
            };
        case actionTypes.FULL_SCREEN_EXIT:
            return {
                ...state,
                isFullScreen: false
            };
        case actionTypes.CHANGE_LAYOUT:
            return {
                ...state,
                layout: action.layout
            };
        case actionTypes.CHANGE_PRE_LAYOUT:
            return {
                ...state,
                preLayout: action.preLayout
            };
        case actionTypes.LAYOUT_TYPE:
            return {
                ...state,
                layoutType: action.layoutType,
                navBackColor: (action.layoutType === 'dark' && initialState.navBackColor === 'navbar-default') ? 'navbar-dark' : state.navBackColor,
                navBrandColor: (action.layoutType === 'dark' && initialState.navBrandColor === 'brand-default') ? 'brand-dark' : state.navBrandColor,
                navBackImage: initialState.navBackImage,
                headerBackColor: initialState.headerBackColor
            };
        case actionTypes.NAV_BACK_COLOR:
            return {
                ...state,
                navBackColor: action.navBackColor,
                navBackImage: initialState.navBackImage,
                navBrandColor: 'brand-default',
                layoutType: (state.layoutType === 'menu-light') ? 'menu-dark' : state.layoutType
            };
        case actionTypes.NAV_BACK_IMAGE:
            return {
                ...state,
                layoutType: 'menu-dark',
                navBackImage: action.navBackImage,
                navBrandColor: '',
                navBackColor: ''
            };
        case actionTypes.NAV_BRAND_COLOR:
            return {
                ...state,
                navBrandColor: action.navBrandColor
            };
        case actionTypes.HEADER_BACK_COLOR:
            return {
                ...state,
                headerBackColor: action.headerBackColor
            };
        case actionTypes.NAV_ICON_COLOR:
            return {
                ...state,
                navIconColor: !state.navIconColor
            };
        case actionTypes.RTL_LAYOUT:
            return {
                ...state,
                rtlLayout: !state.rtlLayout
            };
        case actionTypes.NAV_FIXED_LAYOUT:
            return {
                ...state,
                navFixedLayout: !state.navFixedLayout
            };
        case actionTypes.HEADER_FIXED_LAYOUT:
            return {
                ...state,
                headerFixedLayout: !state.headerFixedLayout,
                headerBackColor: (!state.headerFixedLayout && initialState.headerBackColor === 'header-default') ? 'header-blue' : state.headerBackColor,
                navBrandColor: (!state.headerFixedLayout) ? 'brand-default' : initialState.navBrandColor
            };
        case actionTypes.BOX_LAYOUT:
            return {
                ...state,
                boxLayout: !state.boxLayout
            };
        case actionTypes.LAYOUT6_BACKGROUND:
            return {
                ...state,
                layout6Background: action.value.layout6Background,
                layout6BackSize: action.value.layout6BackSize
            };
        case actionTypes.NAV_DROPDOWN_ICON:
            return {
                ...state,
                navDropdownIcon: action.navDropdownIcon,
            };
        case actionTypes.NAV_LIST_ICON:
            return {
                ...state,
                navListIcon: action.navListIcon,
            };
        case actionTypes.NAV_ACTIVE_LIST_COLOR:
            return {
                ...state,
                navActiveListColor: action.navActiveListColor,
            };
        case actionTypes.NAV_LIST_TITLE_COLOR:
            return {
                ...state,
                navListTitleColor: action.navListTitleColor,
            };
        case actionTypes.NAV_LIST_TITLE_HIDE:
            return {
                ...state,
                navListTitleHide: !state.navListTitleHide,
            };
        case actionTypes.CONFIG_BLOCK:
            return {
                ...state,
                configBlock: !state.configBlock,
            };
        case actionTypes.RESET:
            return {
                ...state,
                layout: initialState.layout,
                preLayout: initialState.preLayout,
                collapseMenu: initialState.collapseMenu,
                layoutType: initialState.layoutType,
                navIconColor: initialState.navIconColor,
                headerBackColor: initialState.headerBackColor,
                navBackColor: initialState.navBackColor,
                navBrandColor: initialState.navBrandColor,
                navBackImage: initialState.navBackImage,
                rtlLayout: initialState.rtlLayout,
                navFixedLayout: initialState.navFixedLayout,
                headerFixedLayout: initialState.headerFixedLayout,
                boxLayout: initialState.boxLayout,
                navDropdownIcon: initialState.navDropdownIcon,
                navListIcon: initialState.navListIcon,
                navActiveListColor: initialState.navActiveListColor,
                navListTitleColor: initialState.navListTitleColor,
                navListTitleHide: initialState.navListTitleHide,
                layout6Background : initialState.layout6Background
            };
        default:
            return state;
    }
}

即使在没有警告或终端错误的情况下进行编译,我在浏览器中仍然遇到下一个错误

  46 | let navLinkClass = ['nav-link'];
  47 | 
  48 | let navItemClass = ['nav-item', 'pcoded-hasmenu'];
> 49 | const openIndex = isOpen.findIndex(id => id === this.props.collapse.id);
     | ^  50 | if (openIndex > -1) {
  51 |     navItemClass = [...navItemClass, 'active'];
  52 |     if (this.props.layout !== 'horizontal') {

我的问题是,为什么将减速器移入CombineReducers函数会导致应用崩溃?

谢谢!!!!!

1 个答案:

答案 0 :(得分:0)

这是因为当您仅包含化简器时,您的状态是一个简单的对象,如下所示:

state {
  isOpen: [],
  ....
}

combineReducers时,您传入具有以下结构的对象:

{ stateKey1: reducer, stateKey2: reducer2...etc }

stateKey1stateKey2实际上是您的redux应用程序的子状态,有助于降低复杂性并保持组件尽可能独立。

在您的情况下,这意味着减速器状态实际上将向下嵌套一层,这意味着您的状态现在看起来像:

state {
  reducer {
    isOpen: []
    ...
  }
}

其中'reducer'是您赋予作为参数传递给combineReducers的对象的键; 要解决此问题,无论您在哪里使用redux状态作为道具,都应像这样访问它们:

const mapStateToProps = state => ({isOpen: state.reducer.isOpen});
相关问题