RedGiant
RedGiant

Reputation: 4748

Store does not have a valid reducer with combineReducer

I have been trying to figure out how to use combineReducers on the server side following the official document.

Here are two of the reducers I'm trying to combine, but no success:

ListingReducer:

import ActionType from '../ActionType'

export default function ListingReducer ( state = Immutable.List.of(), action){
    switch(action.type) {
        case ActionType.ADD:
            return [
                ...state,
                action.item

            ];
        case ActionType.DELETE:
            return state.filter(function(cacheItem){
                return cacheItem.id !== action.item.id;
        });
        default:
            return state
    }
}

DialogShowHideReducer:

import ActionType from '../ActionType'

export default function DialogShowHideReducer ( state = false, action){
    switch(action.type) {
        case ActionType.DIALOG:
            state = action.visible?false:true;
            return state;
        default:
            return state;
    }
}

Store.js (I need to pass some initial data to the listing reducer in order to dynamically add or remove items):

import {createStore} from 'redux';
import { combineReducers } from 'redux';
import ListingReducer from '../reducer/ListingReducer';
import DialogReducer from '../reducer/DialogShowHideReducer';

export default function (initData){
    let listingStore = ListingReducer(initData.item,{});
    let dialogStore = DialogShowHideReducer(false,{'type':'default'});

    // !!!!!!No reducers coming out of this function!!!!!!!!!!
    let combineReducer = combineReducers({
        listing:listingStore,
        dialog:dialogStore
    });

    return createStore(combineReducer)
}

homepage_app.js

import store from './store/Store'
import CustomComponent from './custom_component';

export default class HomePage extends React.Component {

    render() {
        <Provider store={store(this.props)}>
        <CustomComponent/>
        </Provider>
    }

}

But what is this reducer failure error about on page load on the client side?

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

The major difference between the official guide and my exmaple is that I pass the initial state to some reducer before passing them to combineReducers.

Upvotes: 0

Views: 5353

Answers (1)

Michael Helvey
Michael Helvey

Reputation: 4023

The problem is that you're actually not passing functions to your combineReducers function. You're passing the result of your reducer functions, when you do something like let listingStore = ListingReducer(initData.item,{});. This sets listingStore equal to the state returned from the reducer function, instead of the reducer function itself.

If you need to pass initial state to your reducers dynamically (i.e. not hard code them into the reducer), Redux provides a preloadedState argument for the createStore function.

So instead of what you did, you'll want to do something like this:

...
let combineReducer = combineReducers({
    listing: ListingReducer //function
    dialog: DialogShowHideReducer //function
});

let initialState = ... // your initial state here
return createStore(combineReducer, initialState);
...

Upvotes: 3

Related Questions