
В этом видео мы разберем такую тему, как линзы.
Представим себе, что у нас есть объект user с полями firstName и lastName.
const user = {
name: 'John',
surname: 'Flint'
}
И теперь, мы можем создать линзу.
const nameLens = R.lens(R.prop('name'), R.assoc('name'))
Мы создали линзу с помощью R.lens и передали в нее сеттер и геттер для поля name в объекте. То есть, мы описываем то, как получить какое-то поле и как его обновить.
Теперь мы можем, передав в линзу любой объект, знать, что она будет работать именно с полем name.
Давайте попробуем.
В Ramda есть несколько специальных методов для работы с линзами.
Для того, чтобы вызвать геттер, мы можем использовать R.view.
const result = R.view(nameLens, user)
console.log('result')
То есть, при вызове на объект user, у линзы вызвался геттер и мы получили наше поле.
Точно также мы можем вызывать сеттер, чтобы обновить имя.
const result = R.set(nameLens, 'Alex', user)
Мы вызвали set и передали туда линзу и новое имя. В результате, мы получили новый объект с измененным именем.
Обратите внимание, что данные не мутируются.
console.log('user', user)
console.log('result', result)
Представим, что нам нужно у объекта прочитать поле name, сделать все буквы большими и записать результат в новый объект.
С линзой мы можем написать код вот так
const nameLens = R.lens(R.prop('name'), R.assoc('name'))
const name = R.view(nameLens, user)
const upperName = R.toUpper(name)
const result = R.set(nameLens, upperName, user)
console.log('result', result)
То есть мы читаем линзу, вызываем toUpper на результат и обновляем линзу.
Если мы посмотрим в браузер, то все работает.
Но есть возможность написать этот код намного более лаконично.
Вместо этих трех строчек мы можем вызвать метод R.over, который принимает линзу, функцию изменения и объект.
const result = R.over(nameLens, R.toUpper, user)
И результат будет точно таким же.
И, напоследок, давайте напишем наше объявление линзы более сокращенно. Так как R.prop и R.assoc - это самая часто используемая линза, то для нее есть синтаксический сахар.
Мы можем написать
const nameLens = R.lensProp('name')
И все будет работать как и раньше.
Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео.