ReactLens и менеджмент состояния без сложностей на ReactJS
Если ты «кодил» на ReactJS, то скорее всего задавался вопросом, какой менеджер состояния лучше использовать? А сколько их бывает вообще и есть ли альтернативы Redux? В любом случае, эта статья для тебя, мой друг!
В качестве предисловия
А сколько всего менеджеров состояния существует?
Если коротко, то около десятка. Вот некоторые: recoil, Jotai, hookstate, rematch, mobx-state-tree, zustand, react-lens, redux и т.д.
У каждого свои "плюшки". Какие-то хороши для определённого спектра задач. В этой статье мы рассмотрим один из таких менеджеров — react-lens.
Немного о react-lens
react-lens - это новый инструмент, который облегчает работу с состоянием в приложении React. Он предоставляет набор компонентов и утилит для управления состоянием, делая его простым и эффективным.
react-lens нацелен на понятность и переносимость кода, масштабируемость и расширяемость. Основная аудитория — это стартапы и проекты-питомцы. Главная фишка — быстро и без боллерплейта развернуть управление состоянием проекта.
Вот ещё несколько особенностей:
- Инкапсуляция — можно создавать локальные части состояния, закреплённые за отдельным компонентом и переносить его вместе с ним, например на другой проект с другим менеджером состояния.
- Моделирование — react-lens состоит из моделей, которые можно расширять разными способами.
- Асинхронность — менеджер можно использовать в асинхронном коде или внедрять такой код в модели, и не боятся, что что-то пойдёт не так.
- Атомы — состояние может быть разделено на отдельные независимые маленькие кусочки. Это полезно для производительности и масштабирования.
Начнём с примера
Представим, что есть некий компонент — счётчик. Допустим выглядит он вот так:
Теперь подключим его к react-lens…
Это всё! Наш компонент теперь подключён к глобальному состоянию. Если store изменится, то компонент обновится.
Заманчиво? Теперь давайте разберёмся…
Создание состояния
Состояние может быть определено глобально или локально, внутри компонента.
В нашем случае, это глобальное состояние.
Помимо примитивных значений можно хранить и сложные объекты и обращаться к их полям, как к отдельным моделям со своей реализацией.
Есть несколько способов обратиться ко вложенным моделям и данным:
Какой способ выбрать - зависит от задачи и необходимости. Первые два способа эквивалентны и используются для получения модели, связанной с конкретным полем объекта. Последний способ - это простое чтение данных.
Кстати, не нужно никаких редьюсеров. react-lens запишет данные в нужное поле или создаст его, если оно отсутствовало.
Базовый прототип модели уже содержит методы, которые позволяют манипулировать данными, но при желании, его можно расширить собственным функционалом. Сделать это можно двумя способами:
- Наследованием, указав прототип при создании модели
- Функциональным способом, используя метод extends()
Первый способ выглядит так:
Также, мы можем создавать модели, на основе собственных прототипов, для каждого поля в отдельности, указывая его прототип в методе go().
Второй (Функциональный) способ расширения позволяет расширять текущую модель другими, уже созданными моделями. Например, можно добавить метод hello(), используя фабрику.
Кстати, Методы в фабрике могут быть асинхронными.
Если создать некую модель заранее и передать её в метод extends(), как поле объекта, то к этому полю можно будет обратиться через точку.
Теперь, когда мы знаем чуть больше, давайте поместим данные для нашего счётчика во вложенное поле, чтобы иметь возможность расширять наше состояние другими функциями.
Подключение состояния к компоненту
Чтобы компонент начал реагировать на изменение в состоянии, нужно использовать хук `useLens()`, который работает почти также, как и родной `useState()`, за исключением того, что в аргументы следует положить ту часть состояния, которую нужно отслеживать.
В нашем случае, код будет выглядеть следующим образом.
Теперь, если store.counter изменится, то и Counter обновится.
Но можно сделать наш компонент чуть более универсальным. Например, мы хотим, чтобы он мог подключаться к любой модели, имеющей тип — число. Давайте просто пробросим модель, как параметр компонента Counter.
Вот собственно и всё. Теперь компонент может быть использован на любой форме.
Моделирование
Мы уже рассмотрели варианты расширения модели несколькими способами. Давайте попробуем улучшить наш Counter, перенеся логику в модель.
Можно воспользоваться функциональным способом и определить метод increment в модели.
Теперь Counter будет выглядеть так:
А использование его на форме, примерно вот так:
Заключение
Вот так, без лишних усилий мы подключили менеджер состояния и немного углубились в теорию react-lens.
Но не забывайте, что react-lens имеет ещё множество интересных способов проработать ваш проект. Это и трансформирование данных на лету и создание «ленивых» полей ввода, оптимизация и многое другое.
А главное, не придётся тратить много времени на проектирование состояния, что очень важно, особенно, если удастся сберечь ваш солнечный выходной =)