Обрабатываю ли я обновления состояния в этом React Hooks Reducer? - PullRequest
0 голосов
/ 28 февраля 2019

В следующем фрагменте кода у меня есть рабочий редуктор, который я считаю неправильным, поскольку он повторно использует существующее состояние, а не заменяет его.Это работает, хотя без ошибок, которые касаются меня.

  1. Правильно ли не требовать Object.assign?
  2. Если возникнет ошибка, если предположить, что она неверна?
  3. Любые инструменты, которые помогут мне проверить правильностьдля обновлений состояния?

Состояние, которое входит в этот редуктор, представляет собой простой массив с объектами первого уровня.То есть что-то вроде:

const stateIn = [{id: 101,favorite: 0},{id: 102,favorite: 1},...]

А вот редуктор, на который я подозреваю, ниже:

  const speakersReducer = (state, action) => {
    switch (action.type) {
      case "loadspeakers": {
        return action.data;
      }
      case "favorite": {
        return state.map((item, index) => {
          if (item.id === action.sessionId) {
            // let speakerToUpdate = Object.assign(item);
            // speakerToUpdate.favorite = 1;
            item.favorite = 1;
            return item;
            // return speakerToUpdate;
          }
          return item;
        });
      }
      ...
      default:
        return state;
    }
  };
  export default speakersReducer;

1 Ответ

0 голосов
/ 06 марта 2019

Это правильно?

Мутация item находится внутри случая "favorite", на самом деле, подозрительно, как указывал @Tholle.Мутация в редукторах обычно считается анти-паттерном и часто может привести к ошибкам.Я бы определенно рекомендовал изменить его на неизменный шаблон.

Но тогда ...

Почему это не вызывает ошибку, если предположить, что она неверна?

Изменчивость в редукторах является распространенным источником ошибок, но то, вызывает ли конкретный бит мутации ошибку, зависит от того, как он мутировал и как используется редуктор.

Хотя случай с фаворитами может неправильно использоваться повторно item объектов из одной версии состояния в другую, он всегда создает новый массив состояний, так как Array.prototype.map всегда возвращает новый массив.Так, например, useReducer, который заботится только об идентичности объекта внешнего состояния, корректно вызовет повторную визуализацию, несмотря на мутацию.

С другой стороны, селектор редукса, запомненный для определенного элемента в массиве, будет неправильно возвращать старые значения.И если старые items кэшируются и используются повторно, мутация может также вызвать неожиданные ошибки.Но это довольно специфические случаи, поэтому я подозреваю, что в большинстве случаев это сработает.(Я все же изменил бы это, чтобы не изменять, хотя)

Любые инструменты, которые помогли бы мне проверить правильность обновлений состояния?

Что вы хотите, это некоторая форма неизменности: в JS есть несколько библиотек для неизменности.

  • ImmutableJS определяет свои собственные структуры данных со своими собственными API
  • seamless-immutable определяет неизменяемые структуры данных, которые выглядят как обычные изменяемыеиз них
  • immer позволяет выполнять неизменяемые операции с обычным синтаксисом изменяемой операции.

Также Typescript можно использовать по отдельности или в сочетании с этими библиотеками:объекты и массивы должны быть объявлены как только для чтения, и выдает ошибки компилятора, если вы изменяете их.

Также может помочь правило линтера, но оно будет сложным, если вы не согласны с запретом всех мутаций во всей кодовой базе или же вручную включите правило на внутренних редукторах.

...