Линзы — это мощный и элегантный способ сосредоточиться на частях неизменяемых структур данных и манипулировать ими в функциональном программировании. Они предоставляют механизм для получения и установки значений во вложенных объектах или массивах без изменения исходных данных.
Линза — это первоклассная абстракция, обеспечивающая доступ к частям структуры данных и их обновление. Линза обычно определяется двумя функциями: геттером и сеттером.
Линзы особенно полезны для работы с неизменяемыми структурами данных, поскольку они позволяют вносить изменения без изменения исходных данных.
Давайте начнем с базовой реализации линз на JavaScript.
Линзу можно реализовать как объект с помощью методов get и set.
const lens = (getter, setter) => ({ get: (obj) => getter(obj), set: (val, obj) => setter(val, obj), }); const prop = (key) => lens( (obj) => obj[key], (val, obj) => ({ ...obj, [key]: val }) ); // Usage const user = { name: 'Alice', age: 30 }; const nameLens = prop('name'); const userName = nameLens.get(user); console.log(userName); // 'Alice' const updatedUser = nameLens.set('Bob', user); console.log(updatedUser); // { name: 'Bob', age: 30 }
В этом примере prop создает линзу, фокусирующуюся на определенном свойстве объекта. Метод get извлекает значение свойства, а метод set обновляет значение и возвращает новый объект.
Линзы можно составить для работы с вложенными структурами данных. Здесь мы создадим утилиту для составления линз.
const composeLenses = (outerLens, innerLens) => ({ get: (obj) => innerLens.get(outerLens.get(obj)), set: (val, obj) => outerLens.set(innerLens.set(val, outerLens.get(obj)), obj), }); // Usage with nested data const addressLens = prop('address'); const cityLens = prop('city'); const userAddressCityLens = composeLenses(addressLens, cityLens); const user = { name: 'Alice', address: { city: 'Wonderland', zip: '12345', }, }; const userCity = userAddressCityLens.get(user); console.log(userCity); // 'Wonderland' const updatedUser = userAddressCityLens.set('Oz', user); console.log(updatedUser); // { name: 'Alice', address: { city: 'Oz', zip: '12345' } }
В этом примере composeLenses позволяет нам создать линзу, которая фокусируется на свойстве города внутри объекта адреса. Это обеспечивает доступ к вложенным свойствам и их обновление модульным и многоразовым способом.
Линзы особенно полезны в сценариях, где важны неизменяемость и модульное манипулирование данными, например, при управлении состоянием интерфейсных приложений.
В приложении React линзы можно использовать для более функционального и предсказуемого управления обновлениями состояния.
import React, { useState } from 'react'; const App = () => { const [state, setState] = useState({ user: { name: 'Alice', address: { city: 'Wonderland', }, }, }); const userLens = prop('user'); const addressLens = prop('address'); const cityLens = prop('city'); const userAddressCityLens = composeLenses(userLens, composeLenses(addressLens, cityLens)); const updateCity = (newCity) => { const newState = userAddressCityLens.set(newCity, state); setState(newState); }; return (); }; export default App;City: {userAddressCityLens.get(state)}
В этом примере мы используем линзы для модульной организации доступа и обновления вложенного свойства города в состоянии компонента React. Такой подход делает обновления состояния более предсказуемыми и простыми в управлении.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3