На днях ковыряясь в множестве файлов 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. Расширять, дополнять, изменять под свои нужды ведь это так здорово, брать инструмент и делать его идеальным для своих задач.
Автор: bad4iz