根据条件计算项目

IT技术 javascript reactjs redux react-redux
2021-05-21 02:34:01

store的初始状态为:

let initialState = {
  items: [],
  itemsCount: 0,
  completedCount: 0
};

当我用该类型调度一个动作时,ADD_ITEM新项目被添加到items数组中并itemsCount递增(虽然我不确定我是否正确地做)

case "ADD_ITEM": {
  return {
    ...state,
    items: [
      ...state.items,
      {
        title: action.name,
        dateCreated: action.date,
        id: action.id,
        isChecked: false
      }
    ],
    itemsCount: state.items.length + 1
  };
}

并为 TOGGLE_ITEM

case "TOGGLE_ITEM": {
  return Object.assign({}, state, {
    items: state.items.map(item => {
      if (item.id !== action.id) {
        return item;
      }
      return Object.assign({}, item, {
        isChecked: !item.isChecked
      });
    })
  });
}

当我分派具有REMOVE_ITEM以下类型操作时,将执行以下操作:

case "REMOVE_ITEM": {
  return Object.assign({}, state, {
    items: [...state.items.filter(item => item.id !== action.id)],
    itemsCount: state.items.length - 1
  });
}

现在,我想算有项isChecked就是true

state.items.map(item => {
    if(item.isChecked){
        //Increment count
    }
})

我不确定到底在哪里做。

里面的TOGGLE_ITEM动作?

里面有新COUNT_ITEM动作?如果是这样,该操作何时发出?

以及如何为状态的一部分分配一个递增的数字?

3个回答

您可以在操作/组件等中需要时计算它:

items.filter(item => item.isChecked).length

itemsCount在您的状态中存储派生值(例如某些项目(包括变量)的计数)不是一个好习惯(原因类似于您对状态进行标准化的原因)。

如果您担心性能(它是 O(n),所以一般来说应该不是什么大问题),您可以使用memoization library

计数需要重新计算TOGGLE_ITEM以及ADD/REMOVE_ITEM并且计数减速器可以使用 reduce 之类的

state.items.reduce((acc, item) => {
    if(item.isChecked){
        acc += 1;
    }
    return acc;
}, 0)

但是,最好不要将 COUNT 存储在 reducer 中,因为它可以直接从项目派生,您可以简单地memoized selectormapStateToProps函数中使用 a 计算计数您可以利用reselect编写记忆化选择器或创建自己的选择器

只是一个简短的说明,为了减少您的操作代码中的额外开销:

case "ADD_ITEM": {
  let items=state.items
  items.push({
      title: action.name,
      dateCreated: action.date,
      id: action.id,
      isChecked: false
    })
  return {
    ...state,
    items: items,
    itemsCount: state.itemsCount+1
  };
}