I'm using the pattern described here that show us how to reuse reducer logic for other similar purposes.
So, my reducer code is like the code below:
function ContentFilterReducer(entity = ''){
initialState.groupFilter = entity;
return function ContentFilterReducer(state = initialState, action)
{
// is the entity that we want to update?
if (action.item !== undefined && action.item.groupFilter !== entity)
return state;
switch (action.type) {
case ContentFilterTypes.ADD_ITEM:
return {
// we set the
groupFilter: action.item.groupFilter,
listObjects : state.listObjects.push(new Map({
id: action.item.id,
description: action.item.description,
imgSrc: action.item.imgSrc
}))
}
default:
return state;
}
}
}
My combinedReducer describe a reducer for each purpose, as we can see below:
const SearchReducers = combineReducers({
// contains all allowed filters to be selected
UsersContentFilterReducer : ContentFilterReducer(Types.users),
OrganizationsContentFilterReducer : ContentFilterReducer(Types.organizations)
})
Everything is working great, however I'd like to know, how to connect it in a React component using the connect function from React-Redux?
As we can see, I can define the reducer setting an entity (a simple char like 'a', 'o', etc.) and, to call the specific reducer, I need only set the entity in my action. And now, the problem is how to connect a specific reducer for a specific presentational component?
The code below is my HOC container that connect the reducer to a specific component, however, the code is the old version, without defining which reducer should call.
const mapStateToProps = (state, action) => {
return {
contentList: ContentFilterReducer(state.ContentFilterReducer, action)
}
}
/**
*
* @param {contains the action that will be dispatched} dispatch
*/
const mapDispatchToProps = (dispatch) => {
return {
onAddClick: (groupFilter, filterDescription, operator, value) => {
dispatch(AddFilter(groupFilter, filterDescription, operator, value));
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ContentFilterField)
You don't connect a reducer. You connect a component to the Redux store. I won't name my state xxxReducer
, it's a little bit confusing.
I'm not sure what your app looks like, for a simple case, you just need to: (connect both state)
const mapStateToProps = (state) => {
return {
userContentList: state.SearchReducers.UsersContentFilterReducer,
organizationContentList: state.SearchReducers.OrganizationsContentFilterReducer,
}
}
If you want to switch between usersContent
and organizationsContent
dynamically based on your component's state, what you need is a selector
function.
This is the official redux example: https://github.com/reactjs/redux/blob/master/examples/shopping-cart/src/reducers/index.js#L10-L26
These functions are selectors, you import and use them to get the state you want.
So you will create something like getContentList
and it accepts a type
like Types.users
const mapStateToProps = (state) => {
return {
// suppose you save current type saved in SearchReducers.type
contentList: getContentList(state.SearchReducers.type)
}
}
Also, the second parameter of mapStateToProps
is ownProps
not action
.