Состояние области применения в зависимости от срока жизни: когда React Portal действительно нужен глобальный хранилище
Узнайте, как определять, куда должен находиться состояние React Portal по его владельцу и сроку жизни, почему глобальные хранилища приводят к ошибкам при очистке, и в каких случаях действительно оправданы использование Redux или Zustand.
Команды, создающие внутренние порталы, часто начинают обсуждение с вопроса «Redux или Zustand?». Более полезным первым вопросом будет определение того, какие элементы состояния действительно нуждаются в глобальном хранении. В этой статье объясняется, как классифицировать состояние портала по тому, кто им управляет и как долго оно должно существовать, почему хранение кратковременного состояния в глобальном хранилище приводит к постоянным ошибкам при очистке данных, и когда использование глобальной библиотеки является правильным решением.
Большая часть состояния портала имеет кратковременный характер
Порталы обычно представляют собой наборы отдельных рабочих процессов. Пользователь открывает страницу, выполняет поиск или редактирует информацию, завершает задачу и переходит в другую часть приложения. Значения форм, фильтры, выбранные строки таблицы, активная вкладка и наличие открытого модального окна — всё это принадлежит конкретной странице или рабочему процессу. Редко бывает необходимо, чтобы эти данные сохранялись между несколькими не связанными между собой маршрутами.
Только небольшой набор данных действительно является общим для всего приложения:
- залогиненный пользователь;
- статус аутентификации и разрешения;
- текущая организация или арендатор;
- предпочтения по теме и языку.
Почти все остальное должно оставаться связанным с функцией, которая его генерирует.
Глобальные хранилища превращают процесс очистки в постоянную задачу
Если временные данные сохраняются в Redux, Zustand, MobX или любом другом глобальном хранилище, они сохраняются дольше, чем экран, на котором были созданы. Теперь требуется дополнительный код для их сброса при навигации, после отправки данных, при выходе из системы, при смене арендатора и при любом другом выходе с экрана. Если пропустить какой-то из этих моментов, пользователь вернется на экран с устаревшими фильтрами, старыми выборами или неполными значениями формы с предыдущего визита. Эти ошибки трудно воспроизвести, поскольку они зависят от точной последовательности экранов, которые посетил пользователь.
Основное правило простое: если глобальное состояние постоянно приходится очищать, чтобы оно вело себя как локальное, то его, вероятно, следовало с самого начала сделать локальным.
Выбирайте наименьший возможный диапазон
Соотносите каждый элемент состояния с наименее обширным инструментом, который охватывает весь период его существования:
- состояние компонента для поведения интерфейса, связанного с одним компонентом;
- React Context для состояния, общего между одной функциональностью или группой связанных маршрутов;
- параметры поиска в URL для фильтров, пагинации и другого состояния навигации, что также позволяет делиться видами и сохранять их после обновления;
- библиотеку для серверного состояния, такую как TanStack Query, для данных, загружаемых с сервера, поскольку кэширование и аннулирование данных — это её задача, а не задача вашего хранилища;
- глобальное хранилище только для клиентского состояния, которое действительно используется во всем приложении.
Особого внимания заслуживает контекст на уровне маршрутов. Когда вы размещаете провайдер вокруг группы маршрутов, отключение этой группы приводит к демонтированию провайдера, и его состояние автоматически исчезает. Цикл жизни компонентов React выполняет операции очистки, которые в противном случае пришлось бы реализовывать вручную. Если причина, побуждающая вас использовать хранилище состояния, действительно заключается в передаче пропсов через множество уровней, это отдельная проблема с более простыми решениями, о которых рассказано в статье «Почему передача пропсов через множество уровней — не повод для использования Redux или Zustand».
Когда глобальное хранилище состояния оправдано
Redux, Zustand и подобные библиотеки являются правильным выбором, когда состояние должно сохраняться между не связанными экранами намеренно. К типичным случаям относятся:
- кошики покупок;
- сложные процессы оформления заказа, охватывающие несколько страниц;
- наброски, которые должны сохраняться;
- приложения с ориентацией на работу в автономном режиме;
- системы обмена сообщениями или уведомлений внутри приложения;
- функции отмены и повтора действий;
- функции в реальном времени, при которых необходима синхронизация состояния клиента;
- сложные рабочие процессы с множеством взаимозависимых переходов состояния.
В таких ситуациях централизованное управление состоянием решает реальную проблему, а не создаёт новую.
Основные выводы
- Прежде чем выбирать любую библиотеку, определите ответственного за управление состоянием и срок его существования.
- Состояние, принадлежащее конкретному рабочему процессу, должно исчезать вместе с этим процессом, желательно путём его демонтирования, а не ручного сброса.
- Храните серверные данные в библиотеке запросов, а информацию о навигации — в URL.
- Зарезервируйте глобальный хранилище для состояния, которым намеренно пользуется всё приложение в течение времени; умение определить, когда его не использовать, является частью хорошей архитектуры.