创建reducer以更新redux中不同组件的状态

时间:2017-07-21 09:02:07

标签: reactjs redux

我正在使用react和redux创建此UI。以下是UI的图像。 This is image of UI

现在,当点击“类别”时,它会显示数据。然后,当我点击未映射的链接时,它会显示未分类的“类别”产品。但是,当我点击“Addons”然后点击未映射的链接时,它仍会显示“类别”的未映射产品。如何编写reducer以便它也显示“Addons”的未映射产品。在我的react主文件中,我使用(this.props.menu_items)这就是为什么它在Addons之后点击未映射时显示'Categories'的数据。

这是我的reducer文件。

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
 }
 };

1 个答案:

答案 0 :(得分:1)

单击未映射时,我将通过reducer更改的唯一状态是设置unmapped: true / false

无需过滤items数组并将其存储回状态,因为您已经拥有了将组合项目传递到视图所需的所有信息。

在此处阅读有关派生状态和选择器的内容http://redux.js.org/docs/recipes/ComputingDerivedData.html

为了做到这一点,你将使用selector来组合状态的相关部分,以生成从两个项目数组派生的单个项目列表,具体取决于unmapped标志。 reselect库是执行此操作的好帮手,在记忆性能时,只有在任何输入发生更改时才会重新计算,否则返回先前缓存的值

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)} />