一旦包含我的应用程序开始出现故障,我正尝试在我的应用程序中再添加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函数会导致应用崩溃?
谢谢!!!!!
答案 0 :(得分:0)
这是因为当您仅包含化简器时,您的状态是一个简单的对象,如下所示:
state {
isOpen: [],
....
}
combineReducers
时,您传入具有以下结构的对象:
{ stateKey1: reducer, stateKey2: reducer2...etc }
stateKey1
和stateKey2
实际上是您的redux应用程序的子状态,有助于降低复杂性并保持组件尽可能独立。
在您的情况下,这意味着减速器状态实际上将向下嵌套一层,这意味着您的状态现在看起来像:
state {
reducer {
isOpen: []
...
}
}
其中'reducer'
是您赋予作为参数传递给combineReducers
的对象的键;
要解决此问题,无论您在哪里使用redux状态作为道具,都应像这样访问它们:
const mapStateToProps = state => ({isOpen: state.reducer.isOpen});