Используя React Hooks useReducer, как мне эффективно обновить объект по ID?

У меня есть 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;
    };
  }
}

Я чувствую, что ответ похож на этот? Обновление объекта массива в редукторе React Redux

В ответе, который я цитировал выше, его объект state.posts Как я могу обновить свой пример, чтобы он больше походил на этот?

Как я могу нацелить свой Todos, если у меня нет подобного объекта состояния, поскольку я не могу сделать что-то вроде:

state.todos.complete = false.

Я хочу написать лучший редуктор для действия "ЗАВЕРШЕНО". Нужно ли мне модифицировать структуру моего состояния, то есть допустить, что он должен быть пустым объектом вместо массива объектов?

1 ответ

Просто map:

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

Вы можете условно обновить "завершить", не повторяя несколько раз.

Другие вопросы по тегам