Redux CombineReducers与多个文件-犯了一个简单的错误

时间:2019-04-25 12:30:24

标签: ecmascript-6 redux

我正在尝试按照@gaearon的答案(https://github.com/reduxjs/redux/issues/609#issuecomment-133903294)设置从多个文件组合减速器的模式,但是我犯了一个简单的错误,无法弄清它是什么。在这个脑袋上有些脑袋...:\

出现以下错误:

Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers.

我的代码:

containers / score / reducers.js

export const goals = (state = 0, action) =>
  action.type === types.UPDATE_GOALS ? action.payload : state

export const points = (state = 0, action) =>
  action.type === types.UPDATE_POINTS ? action.payload : state

containers / time / reducers.js

export const minutes = (state = 0, action) =>
  action.type === types.UPDATE_MINUTES ? action.payload : state

export const seconds = (state = 0, action) =>
  action.type === types.UPDATE_SECONDS ? action.payload : state

containers / index.js

import * as score from './score'
import * as time from './time'

export default Object.assign({}, score, time)

store / configureStore.js

import { createStore, combineReducers } from 'redux'
import reducers from '../containers'

const configureStore = initialState =>
  createStore(combineReducers(reducers), initialState)

export default configureStore

components / provider.js

import configureStore from '../store/configureStore'
const initialState = { minutes: 55 }
const store = configureStore(initialState)

在大型代码库上,仅将reducer直接导入configureStore文件是不够的。您拥有这些巨大的状态树,这些树需要数百个reducer文件,并且许多reducer从其他文件导入其他reducer。基本上,我是在问如何管理化简的深度嵌套状态树,并使用importexport逐一合并它们,直到它们到达根combineReducers函数。

2 个答案:

答案 0 :(得分:2)

如果在CombineReducer内部传递的对象为空或无效,则会看到该错误。

我总是这样构造减速器

  1. 我不会为每个操作都分离导出,而是将它们合并为一个导出并使用切换案例进行管理。
  2. 在化简器中定义每个化简器的initialState以便于代码管理。

我已经稍微重写了您的代码:

containers / score / reducers.js

const initialState = {
  goals: 0,
  points: 0
};

const scoreReducer = (state = initialState, action) => {
  switch (action.type) {
    case UPDATE_GOALS:
      return { ...state, goals: action.payload };
    case UPDATE_POINTS:
      return { ...state, points: action.payload };
    default:
      return state;
  }
};
export default scoreReducer;

containers / time / reducers.js

const initialState = {
  minutes: 0,
  seconds: 0
};

const timeReducer = (state = initialState, action) => {
  switch (action.type) {
    case UPDATE_MINUTES:
      return { ...state, minutes: action.payload };
    case UPDATE_SECONDS:
      return { ...state, seconds: action.payload };
    default:
      return state;
  }
};
export default timeReducer;

containers / index.js

import score from './score';
import time from './time;
import { combineReducers } from "redux";
const rootReducer = combineReducers({
  score,
  time
});

export default rootReducer;

在此之后,我不会再复杂了-在定义组合的reducer之后,我只是将提供者传递并存储到我的主要包装器组件中:

src / index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Router } from 'react-router-dom';
import { Provider } from 'react-redux';
import rootReducer from './container';
import history from './history';
import App from './App';

const store = createStore(
  rootReducer
);

ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
      <App />
    </Router>
  </Provider>,
  document.getElementById('root')
);

我真的认为以这种方式构造可以解决您的问题,请尝试。

答案 1 :(得分:1)

似乎分数和时间文件夹中不包含index.js文件。

尝试添加它们或更改您的 containers / index.js 文件:

    javafx.fxml.LoadException: 
/U:/Developpement/IntelliJ/Statistiques/out/production/Statistiques/ui/FXML/HomePage.fxml

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
    at main.Main.start(Main.java:35)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
    at main.Menu.setMenuBarColor(Menu.java:35)
    at main.HomePage.initialize(HomePage.java:38)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
    ... 12 more