Мои последние два поста были на Утки высшего порядка. Мы построили один, затем отрефакторили его с помощью помощника createReducer
.
Как и было обещано в последнем, время Рамды. Если вы найдете лучший способ реализовать что-то, пожалуйста, дайте мне знать! ❤️
Что это?
Ramda - это библиотека, которая упрощает функциональное программирование на JavaScript. Многие из наших рукописных шаблонов Redux легко выражаются в одной или двух функциях Ramda.
Я намеренно злоупотреблю Рамдой, чтобы продемонстрировать ее силу. Я не обязательно буду делать все в этом посте, но научиться понимать эти закономерности никогда не помешает.
Покажи мне код
Если вы читали предыдущую статью, вы помните, как мы реорганизовали редюсер так:
Хотя я намного больше доволен кодом после того, как пропустил его createReducer
, Ramda предоставит дополнительную поддержку. Давайте начнем с дела reset
и спустимся вниз.
actionTypes.reset
() => initialState
Все, что делает reset
, - это возвращает исходное состояние. Чем может помочь Рамда?
R.always(initialState)
Берем initialState
и запихиваем в R.always
.
Из Документов Ramda:
Возвращает функцию, которая всегда возвращает заданное значение.
Вместо стрелочной функции у нас есть красивая R.always
функция. Это может быть излишним, но я намеренно преувеличиваю, чтобы продемонстрировать часть арсенала Рамды.
actionTypes.addOne
(state, { item }) => [...state, item]
Объединить state
(список) с заданным item
.
(state, { item }) => R.append(item, state) // or (state, { item }) => R.concat(state, [item])
Возвращает новый список, содержащий содержимое данного списка, за которым следует данный элемент.
Возвращает результат объединения заданных списков или строк.
Используйте R.append
, чтобы создать новый список с item
в конце, или превратите item
в массив и объедините его в state
с R.concat
.
actionTypes.addMany
(state, { items }) => [...state, ...items]
На этот раз items
уже является списком, и мы хотим объединить его с state
.
Мы уже знаем, что R.concat
добивается цели.
(state, { items }) => R.concat(state, items)
Вот код на данный момент.
actionTypes.removeOne
(state, { oldItem }) => state.filter((item) => ( !findItemById(oldItem.id)(item) )),
Напомним, что мы определили findItemById
как:
findItemById = (id) => (item) => item.id === id;
Если findItemById(id)(item)
возвращает false
, оставьте элемент, в противном случае удалите его. Подведем итоги:
Видеть? Мы передали foods
редуктору, а removeOne
- id: 1
. findItemById
вернул true
для нашего mango
, поэтому он был удален.
У этого есть много переводов в Рамде.
Вы можете заменить state.filter
на R.filter
:
Вместо логического оператора НЕ, !
, мы можем использовать R.not
.
Мы можем скрыть параметр item
с помощью R.complement
.
Теперь мы становимся дерзкими. R.complement
передаст item
findItemById(oldItem.id)
и вернет противоположное тому, что возвращает. Если findItemById(1)(item)
вернет true
, R.complement
вернет false
.
Однако было бы неплохо вообще не отрицать findItemById
. Вы когда-нибудь слышали о R.reject
?
Вместо дополнения findItemById
мы можем использовать дополнение filter
– R.reject
!
Бум!
Это означает, что когда findItemById(id)(item)
вернет true
, R.reject
исключит item
вместо того, чтобы включать его, как filter
. За нас проделана тяжелая работа, и наш код стал намного проще.
actionTypes.updateOne
У Рамды есть R.map
. Начнем с этого.
Но это даже не окончательная форма updateOne
: введение R.when
.
Обобщая документацию, R.when
принимает три параметра: predicate
, whenTrueFn
и ваш тестовый объект x
.
Если predicate
вернет true
, вы вернетесь whenTrueFn(x)
.
В противном случае вы вернетесь только x
.
Простой пример. Давайте увеличим число, только, если оно равно 1.
В случае updateOne
мы использовали R.when
для инкапсуляции нашей предыдущей троичной логики. Если findItemById(id)(item)
найдет совпадение и вернет true
, мы вернем newItem
. В противном случае мы просто вернем полученный item
.
actionTypes.set
[actionTypes.set]: (_, { items }) => items
Это так просто, у меня нет хороших идей. Так вот плохой.
[actionTypes.set]: R.pipe( R.nthArg(1), R.prop('items') )
Как сказал бы мой старый босс: Лол.
Силой R.pipe
мы возвращаем свойство items
второго аргумента. Это все, что у меня есть для тебя ...
Если вам интересно, как работает свёртка / компоновка, смотрите мою статью об этом.
Пожалуйста, хлопайте в ладоши / комментируйте, если вам понравилось! До скорого!
Береги себя,
Язид Бзадоу