Как стать автором
Обновить

Redux — пересмотр логики reducer'a и actions

Время на прочтение3 мин
Количество просмотров18K


На днях ковыряясь в множестве файлов redux'a, где по логике файлы вынесены в reducers, actions, константы типов actions. Bсе это оказалось весьма не простая задача держа все эти типы файлов у себя в голове и прослеживать логику. И… эврика, появилась идея упрощения написания redux логики. Возможно создавая свой велосипед, но кто не пытался писать свои велосипеды? Но главное это не написание а поддержка написанного когда. Давайте я вам немного постараюсь показать свое видение моей логики redux'a.


Начало


И так у нас есть reduce:


// импортируем константы
import { TODO } from './actions/const';
.....
// может быть ооочень много импортов 
....

// и наконец наш reducer
function todoApp(state = initialState, action) {
  switch (action.type) {
    case TODO.SET_VISIBILITY_FILTER:
      return Object.assign({}, state, {
        visibilityFilter: action.filter
      })
    case TODO.ADD_TODO:
      return Object.assign({}, state, {
        todos: [
          ...state.todos,
          {
            text: action.text,
            completed: false
          }
        ]
      })
    case TODO.TOGGLE_TODO:
      return Object.assign({}, state, {
        todos: state.todos.map((todo, index) => {
          if (index === action.index) {
            return Object.assign({}, todo, {
              completed: !todo.completed
            })
          }
          return todo
        })
    })
   ...
  тут тоже может быть ооч много букв и вырастает до... ну в общем только поиск тебе поможет в этом лапшевидном файле
   ...
    default:
      return state
  }
}

взят из оф доки по redux.


action имеет вида типа:


// импортируем константы
import { TODO } from './const';

export const addTodo = (value) => ({
  type:  TODO.ADD_TODO,
  payload: value
})

константы я думаю нет необходимости показывать.


БООЛЬ


Попробую описать неистовство которое я испытываю читая код особенно при дебаге или расширении функционала.


  • поиск — нужно все время нажимать Ctrl + F причем глобально Ctrl + Shift + F
  • не видно сразу от куда ноги растут. Вытекает из пункта выше.
  • нет, это всего мало, так у меня еще весь проект пронизывают константы. Нет я не против констант но зачем? Тем более если их использовать вместе с вложенностью как в примере да если еще их конкатенировать из нескольких то это вообще ад навигации.
  • логика размазана. В одном месте действия в другом обработка этих действий в третьем (опционально) константы которые нужны только тем двум.
  • мне нужно при разработке или дебаге держать открытыми много файлов. Вытекает из пункта выше.
    ну и тп.

Вступление в логику


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


reducer


подсмотрено в google


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

То есть вал на нем есть шестерня эта шестерня передает другой шестерне вращение которая в свою очередь своему валу. Убираем вал и вместе с ним убирается шестерня. Не разрывный так сказать модуль.


Если провести аллегорию дальше то вал это действие а шестерня это логика. От сюда вытекает что редуктор выступает таким связующим звеном в обеспечении передачи вращающего момента то есть данных в приложении. Он должен поддерживать идеальное окружение работы механизмов.


action


Как было сказано выше это само действие, и логика того какую энергию передать (в нашем случае данные).


И так поехали. Мой Велосипед


reducer:


export function todoApp(state = initialState, action) {
    if (typeof action.func === 'function') {
        return action.func(state);
    }
}

да это весь мой reducer. Щас возможно будет небольшой разрыв шаблонов, как? мы вынесли логику из reducer'a..? Да. скажу я вам, мы вынесли логику из reducer'a!!!


Давайте посмотрим на action:


export function addTodo = (value) => ({
    type:  'ADD_TODO' ,
    payload: value,
    func: (state) =>({...state, value})
  })
}

Вот ради этого мы вынесли логику отвечающую за передачу данных стору. Reducer остался обеспечивать работу всего механизма. И он должен делать это хорошо не отвлекаясь на вещи его не касающиеся. А нам остается только наблюдать порядок в том от куда растут ноги и если надо то быстро найти и исправить или дополнить.


Стоит заметить Мы убрали константы. Да и switch тоже. Что позволило снизить сложность выполнения О(1) в reducer'e.


Это всего лишь пример-набросок который вы можете расширить и убрать combineReducers. Расширять, дополнять, изменять под свои нужды ведь это так здорово, брать инструмент и делать его идеальным для своих задач.


И главное хочется сказать.



Будьте умничками. бэээ

Теги:
Хабы:
Всего голосов 27: ↑16 и ↓11+5
Комментарии33

Публикации

Истории

Работа

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань