Banging my head on this. I've blown through the typical ReactJS and Redux app tuts and am working on my own app. The problem is when using combineReducers() to create a single reducer for the Redux store. I currently have three reducers which, on their own, work fine when when added as the reducer param for createStore(). The first reducer holds all of my actions and is called:
HeaderReducer
import { isActive } from '../actions/HeaderActions';
export const initialButtonState = {
isActive: false,
invertStyles: false
}
export default (state = initialButtonState, action) => {
switch (action.type) {
case 'SET_ACTIVE':
return {
...state,
isActive: action.isActive(state),
invertStyles: action.invertStyles(state),
}
default:
return state
}
}
The second and third reducer are built using ImmutableJS to propagate some dummy content for separate lists. Again, individually these reducers work on their own but do not when combineReducers() combines them. The second reducer file is called:
ListItems
import Immutable from 'immutable';
const messagesList = Immutable.List(['9:00AM - 9:30AM','10:30AM - 11:30AM','11:45AM - 12:30PM','1:00PM - 2:15PM','3:00PM - 4:00PM']);
export default (state = messagesList, action) => {
switch(action.type) {
case 'addItem':
return state.push(action.item)
case 'deleteItem':
return state.filter((item, index) => index !== action.index)
default:
return state
}
}
The third file is called:
QuotesList
import Immutable from 'immutable';
const quotesList = Immutable.List(['Company A: 100.00$','Company B: 200.00$','Company C: 300.00$','Company D: 400.00$','Company E: 500.00$<']);
export default (state = quotesList, action) => {
switch(action.type) {
case 'addItem':
return state.push(action.item)
case 'deleteItem':
return state.filter((item, index) => index !== action.index)
default:
return state
}
}
I have all files exported via an index.js within the reducers folder:
index.js
export { default as HeaderReducers } from './HeaderReducers';
export { default as ListItems } from './MessageList';
export { default as QuotesList } from './QuotesList';
and then called in to create my store in:
Store.js
import { createStore, combineReducers } from 'redux';
import * as reducers from '../reducers';
// import HeaderReducers from '../reducers/HeaderReducers';
// import ListItems from '../reducers/MessageList';
// import QuotesList from '../reducers/QuotesList';
// let reducer = combineReducers({ ListItems: ListItems, quotes: QuotesList})
// export default createStore(ListItems)
const reducer = combineReducers(reducers);
export default createStore(reducer);
Logging the state of the store at launch returns an Object or List, depending on the reducer I use. When I run them through combineReducer(), I get a single Object returned holding each reducer together. What breaks immediately is a .map function I have setup in ListItems.js
import React from 'react';
import { connect } from 'react-redux';
import NewItem from './NewItem';
import { addItem, deleteItem } from '../../../actions/HeaderActions';
const ListItems = ({ListItems, dispatch}) => (
<div>
<ul>
{ListItems.map((ListItem, index) => <li><span key={index}> {ListItem} <button onClick={e => {
dispatch(deleteItem(index))
}}>X</button></span></li>)}
</ul>
<NewItem />
</div>
)
function mapStateToProps(ListItems) {
return {
ListItems,
}
}
export default connect(mapStateToProps)(ListItems)
Console shows "_ListItems.map is not a function". I've gone through and tried editing the mapStateToProps return value but I'm grasping at straws. Thanks for reading this. Any help is definitely appreciated.
The combineReducers helper function turns an object whose values are different reducing functions into a single reducing function you can pass to createStore .
Having multiple reducers become an issue later when we create the store for our redux. To manage the multiple reducers we have function called combineReducers in the redux. This basically helps to combine multiple reducers into a single unit and use them.
There are several reasons why you must not mutate state in Redux: It causes bugs, such as the UI not updating properly to show the latest values. It makes it harder to understand why and how the state has been updated. It makes it harder to write tests.
The only way to update a state inside a store is to dispatch an action and define a reducer function to perform tasks based on the given actions. Once dispatched, the action goes inside the reducer functions which performs the tasks and return the updated state to the store. This is what Redux is all about.
combineReducers doesn't support immutable. Try redux-immutable combineReducers instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With