Удаление Redux

Комедия ошибок.

Redux — это паттерн управления состояниями, который появился несколько десятилетий назад, задолго до того, как он стал популярен в эпоху веб. Как и все популярные вещи, он имеет много приверженцев и противников. Почти в каждом месте, где я работал, его использовали хотя бы в одном проекте. Нравится вам это или нет, но redux — это основа Интернета, каким мы его знаем сегодня.

Если вы уже использовали redux, вы знаете, что он поставляется с невероятным количеством шаблонов, непрямолинейности и путаницы. Постарайтесь не отводить взгляд, глядя на этот простой пример, который вы можете найти в учебнике.

const Increment = createAction("Increment", props<{ by: number }>())
const Double = createAction("Double")

class UICounterEffects {
   double = createEffect((actions) => {
      return actions.pipe(
         ofType(Increment),
         map(action => new Double()),
         delay(2000),
      )
   })
}

function countReducer(state, action) {
   switch(action.type) {
      case Increment.type: {
         return state += action.by
      }
      case Double.type: {
         return state *= 2
      }
   }
}

const countSelector = createSelector(state => state.count)

const initialState = {
  count: 0
}

const REDUCERS = {
  count: countReducer
}

const Store = createStore(REDUCERS, {
   initialState,
   effects: [UICounterEffects]
})

@Component({
   providers: [Store],
   template:
      <div>{{ count | async }}</div>
      <button (click)="increment(1)">
         Increment
      </button>
})
export class UICounter {
   private store = inject(Store)

   count = this.store.select(countSelector)

   increment(by) {
      this.store.dispatch(new Increment({ by }))
   }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Святой Бэтмен чрезмерной инженерии! Так много кода для такого малого количества действий. Давайте посмотрим, как это выглядит без redux.

@Component({
   template:
      <div>{{ count }}</div>
      <button (click)="increment(1)">
         Increment
      </button>
})
export class UICounter {
   // we initialize some state
   count = 0
   // we dispatch an action
   increment(by) {
      // we update the state
      this.count += by
      // we run some effects
      setTimeout(() => {
         // we update the state again
         this.count *= 2
      }, 2000)
   }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Первый пример — это 1136 байт кода в 56 строках. Второй пример делает то же самое всего за 301 байт в 18 строках! Он также на порядок легче для чтения и понимания.


Очевидно, что-то не так с людьми, которые используют redux.


А как насчет «инструментов Dev», «путешествия во времени» и «неизменяемого состояния»? Я говорю, что они сильно переоценены и излишни. Сделайте одолжение следующему парню, удалите redux из своего приложения.

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

Даже если вы не можете удалить redux из своего приложения, это не страшно. Просто перестаньте использовать его для всего.

@Component({
   template:
      <div>{{ count }}</div>
      <button (click)="increment(1)">
         Increment
      </button>
})
export class UICounter {
   // we initialize some state
   count = 0
   // we dispatch an action
   @Action() increment(by) {
      // we update the state
      this.count += by
      // we run some effects
      return dispatch(timer(2000), () => {
         // we update the state again
         this.count *= 2
      })
   }
}

Вход в полноэкранный режим Выход из полноэкранного режима

Приемлемое количество шаблонов

Оцените статью
devanswers.ru
Добавить комментарий