Reputation: 93
I am creating this UI using react and redux. Below is the image of the UI. This is image of UI
Now it currently displays the data when 'Categories' is clicked. Then when I click on unmapped link ,it shows unmapped products of 'Categories'. But when I click on 'Addons' and then on unmapped link ,it still shows the unmapped products of 'Categories'. How do I write the reducer so that it shows the unmapped products of 'Addons' as well. In my react main file I use (this.props.menu_items) that's why it shows the data of 'Categories' when clicked unmapped after Addons.
This is my reducer file.
import { AppConstants } from '../constants';
const initialState = {
state: [],
menu_items: [],
menu_items_copy: [],
addon_items: [],
unmapped: false,
};
export default (state = initialState, action) => {
switch (action.type) {
case AppConstants.getMenuItems:
return {
...state,
}
case AppConstants.getMenuItemsSuccess:
return {
...state,
menu_items: action.menu_items,//This contains the data showed when
// 'categories' is clicked
menu_items_copy: action.menu_items,
unmapped: false,
}
case AppConstants.getAddonsItems:
return {
...state,
}
case AppConstants.getAddonsItemsSuccess:
return {
...state,
menu_items: action.addon_items,//Here I update the data to addons data
}
case AppConstants.showAllProducts:
return {
...state,
menu_items: action.menu_items,
unmapped: false
}
case AppConstants.getUnmappedMenuItemsSuccess:
return {
...state,
unmapped: true,
menu_items: state.menu_items_copy.filter((item) => {-->How do I write
here for action.addon_items also
return (item.productList.length == 0)
})
}
case AppConstants.hideError:
return {
...state,
error: null
}
default:
return state
}
};
Upvotes: 0
Views: 543
Reputation: 4522
The only state I would change via reducer when unmapped is clicked would be to set unmapped: true / false
.
There is no need to filter the items array and store it back into the state, as you already have all the info you need to derive your combined items at the point where you pass it to the view.
Have a read about derived state and selectors here http://redux.js.org/docs/recipes/ComputingDerivedData.html
In order to do this you would use a selector
to combine the relevant parts of your state to produce a single list of items that is derived from both the items arrays, depending on the unmapped
flag. The reselect
library is a great helper to do this while memoising for performance, it will only recompute if any of the inputs change, otherwise returns the previously cached value
import {createSelector} from 'reselect'
const selectMenuItems = state => state.menu_items
const selectAddonItems = state => state.addon_items
const selectUnmapped = state => state.unmapped
const selectItemsToShow = createSelector(
selectMenuItems,
selectAddonItems,
selectUnmapped,
(menuItems, addonItems, unmapped) => {
// if unmapped is set - combine all items and filter the unmapped ones
if (unmapped) {
return menuItems.concat(addonItems).filter(item => !item.productList.length)
}
// else just return the menu items unfiltered
return menuItems
}
)
// this selector can then be used when passing data to your view as prop elsewhere
// or can be used in `connect` props mapping as in the linked example)
<ItemsList items={selectItemsToShow(state)} />
Upvotes: 1