使用 React Hooks useReducer,如何有效地按 ID 更新对象?

Using React Hooks useReducer, how can I update an object by ID efficiently?

我有一个可以分叉的 StackBlitz,我找到了一个类似的答案,但我无法将其应用到我的示例中,我认为这是因为我有一个对象数组。

我的代码可以工作,但它非常冗长,我想要一些更容易阅读的东西,其他使用 Redux 的人会认得。

const initialState = [];
const todoReducer = (state, action) => {
  switch (action.type) {
    case 'ADD_TODO': {
      return [...state, {
        id: state.length,
        name: action.name,
        complete: false
      }];
    }
    case 'TOGGLE_COMPLETE': {
      let left = state.filter((_, index) => index < action.index)
      let right = state.filter((_, index) => index > action.index)
      let completed = state.filter((_, index) => index == action.index)
      let updatedItem = {
        id: completed[0].id,
        name: completed[0].name,
        complete: !completed[0].complete
      }
      return [...left, updatedItem, ...right];
    }
    case 'CLEAR': {
      return initialState;
    }
    default: {
      return state;
    };
  }
}

我觉得这个答案和这个差不多?

在我上面引用的答案中,他的对象有 state.posts 我如何更新我的示例以使其更像这个?

如果我没有类似的状态对象,我该如何定位我的待办事项,因为我不能做类似的事情:

state.todos.complete = false.

我想为 'COMPLETE' 动作写一个更好的减速器。我是否需要修改我的状态的结构,即它是否需要是一个空对象而不是对象数组?

map:

case 'TOGGLE_COMPLETE': {
  return state.map((item, i) => i === action.index 
    ? {...item, complete: !item.complete}
    : item
  )
}

您可以有条件地更新 "complete" 而无需多次迭代。