(если нужна - Redux vs Recoil)
#Recoil #React #JS #ReactJS #CRM #SUREcrm #state management #управление состоянием react #разработка приложений #программирование
Что вам нужно знать, прежде чем использовать React-библиотеки, такие как Redux
Если вы читаете это, вам, вероятно, интересно, нужна ли вашему приложению или веб-сайту сторонняя библиотека для управления состоянием — или, возможно, вы думаете, что она вообще не нужна.
Здесь я объясню, когда это может стоить того, а когда может оказаться бесполезным для вашего приложения.
Состояние в React: Возможные проблемы
Если вы разработчик React, возможно, вы не знаете, что состояние - это не специфическая концепция React, а общая концепция JavaScript.
Это основная концепция, потому что она отслеживает статус нашего приложения и описывает его с течением времени.
В частности, React-приложение состоит из нескольких компонентов, каждый из которых может иметь состояние, и с введением хуков мы можем использовать также состояние внутри функциональных компонентов.
Независимо от того, используем ли мы функциональные или классовые компоненты, при работе с React мы передаем данные от родителей дочернему элементу через props.
Иногда эти данные должны быть разделены между большим количеством дочерних элементов внутри приложения, и иногда эти компоненты отстоят друг от друга очень далеко внутри дерева компонентов.
С ростом нашего приложения это может стать первой проблемой для производительности и качества кода.
Если мы хотим разделить состояние между большим количеством дочерних элементов, нам нужно сохранить его в компоненте более высокого уровня.
Поступая так, и особенно если наша структура более сложна, чем to-do приложение, мы можем столкнуться со второй проблемой.
Мы знаем, что re-rendering React-компонента происходит автоматически, если происходит re-rendering родительского компонента или обновление его props или состояния.
Таким образом, каждый раз, когда происходит изменение состояния в родительском элементе, происходит re-rendering всех дочерних элементов, даже если они не используют состояние, ставшее причиной перерисовки родительского элемента.
Если в вашем браузере Chrome установлены react-dev-tools, вы можете легко проверить это, включив опцию “Highlight updates when components render”(“Выделять обновления при отображении компонентов”).
Конечно, повторный рендеринг не означает, что происходит реальное обновление объектов в DOM.
Это связано с тем, что React использует виртуальный DOM, виртуальное представление DOM.
Каждый раз, когда меняется состояние нашего приложения, виртуальный DOM обновляется вместо реального DOM. Каждый раз, когда объект в виртуальном DOM изменяется, React обновляет только эти объекты в реальном DOM.
Взгляните на замечательную статью Кента К. Доддса.
ContextAPI: Стоит ли оно того?
Иногда мы думаем, что решением может быть использование ContextAPI, чтобы мы могли избежать передачи реквизитов через промежуточные элементы.
Короче говоря, мы используем специальный объект - Provider для передачи значений(контекста) в приведенное ниже дерево, и любой компонент может его прочитать.
Компоненты, использующие передаваемые данные, называемые Consumer , которые являются потомками этого объекта Provider, могут подписаться на изменения контекста.
Все элементы, отображающие данные, переданные через Consumer, будут перерисовываться всякий раз, когда изменяются данные объекта Provider.
Таким образом, Context предоставляет способ передачи данных через дерево компонентов без необходимости передавать props вручную на каждом уровне. (См: https://it.reactjs.org/docs/context.html)
С помощью такого решения мы можем разделить состояние с дочерними элементами, но вторая проблема остается, потому что, если значения внутри контекста изменятся, все компоненты все равно будут повторно отображаться.
Из-за этого ContextAPI может быть полезен только в нескольких ситуациях, например, при смене предпочтительной темы, языка и настроек, поскольку изменение их значений происходит не очень часто.
Это хорошее решение проблемы детализации пропсов, которая представляет собой ситуацию, когда данные передаются из компонента более высокого уровня в компонент более низкого уровня, и мы хотим избежать передачи пропсов на каждый уровень дерева.
Таким образом, мы можем использовать его для решения первой проблемы разделения состояния с дочерними элементами, но нам нужно что-то еще, чтобы предотвратить повторный рендеринг.
Возможное решение: сторонняя библиотека
Решением для этого является использование сторонней библиотеки для управления состоянием для улучшения качества и производительности кода.
Существует множество интересных библиотек, позволяющих разделять состояние между всеми компонентами приложения и сохранять его в хранилище, например Recoil или Redux.
Использование такого рода библиотек позволяет нам обмениваться данными между всеми компонентами и в то же время сохранять код простым и предотвращать повторный рендеринг.
Таким образом, только те компоненты, которым требуется это значение, будут повторно отображены, и они также могут изменить состояние.
Redux
Одной из самых известных библиотек для обработки сложной и вложенной логики состояний, является Redux, библиотека, использующая единое хранилище состояния.
Все глобальное состояние вашего приложения хранится в дереве объектов внутри одного хранилища. Единственный способ изменить дерево состояний - это создать действие(action), объект, описывающий, что произошло, и отправить(dispatch) его в хранилище. Чтобы указать, как состояние обновляется в ответ на действие, вы пишете чистые функции-редьюсеры(reducer), которые вычисляют новое состояние на основе старого состояния и действия. См: https://redux.js.org/
Я не буду объяснять, как работает Redux, потому что есть много руководств, но я только хочу подчеркнуть улучшения, которые произошли с внедрением Redux Toolkit.
Изначально созданный для сокращения шаблонного кода (boilerplate) “классического” Redux и упрощения настройки хранилища, он является стандартным способом написания логики Redux.
Попробовав Redux Toolkit, я увидел, насколько проще стало писать Redux-код, особенно с введением функции createSlice. Я думаю, что Redux Toolkit, - очень мощная и устоявшаяся библиотека, но даже после этого, я думаю, Redux-код остается громоздким, особенно для новичка.
Но есть еще одна библиотека, которая делает все это простым и минималистичным.
Recoil
Recoil - это очень молодая библиотека с открытым исходным кодом, созданная инженером-программистом из Facebook, чтобы, по-видимому, решить именно нашу проблему с управлением состоянием.
Она предоставляет глобальное состояние, подобное Redux, поэтому мы можем поделиться им со всеми компонентами нашего приложения, но минималистично и лаконично по сравнению с другими библиотеками, что заставит вас сразу влюбиться в неё.
Она помогает вам сохранять код очень простым, без дополнительной логики, сокращая время обучения для новых пользователей.
Это также идеальный выбор для уже существующих проектов.
Если коротко: Recoil использует единицы состояния, называемые атомами, на которые могут подписываться компоненты. Когда обновляется атом, каждый подписанный компонент повторно отображается с новым значением.
Также, Recoil предоставляет функцию под названием Selector, используемую для создания состояния производного(зависящего) от других данных (атомов и селекторов). Если объекты-источники поменяют состояние – автоматически поменяется и состояние зависимого селектора и перерисуется элемент, его использующий.
Атом представляет собой часть состояния. Атомы могут быть прочитаны и записаны из любого компонента. Компоненты, считывающие значение атома, неявно подписаны на этот атом, поэтому любые обновления атома приведут к повторному отображению всех компонентов, подписанных на этот атом. См.: https://recoiljs.org/
Я не буду писать подробное руководство также и по Recoil, но я только хочу подчеркнуть простоту реализации и использования.
Глобальное состояние Recoil имеет тот же простой get/set интерфейс, что и локальное состояние React.
Чтение и запись элементов состояния Recoil очень просты, как и useState hook.
Функции atom очень лаконичны, вы можете начать использовать Recoil там, где вам это нужно, с очень небольшим количеством строк кода.
Как использовать Recoil в вашем приложении: мой подход
Простота внедрения Recoil или огромная популярность Redux могут послужить причиной неоправданного выбора для разработчиков, у которых может возникнуть соблазн злоупотреблять использованием внешней библиотекой управления состояниями буквально в каждом приложения.
Такую библиотеку действительно легко использовать для решения всех проблем без каких-либо усилий, но мы должны быть осторожны, потому что злоупотребление этими инструментами может снизить производительность приложения.
Внешнюю библиотеку лучше использовать там, где нам нужно разделить состояние между многими компонентами или в очень вложенных компонентах. В большинстве случаев, когда нам нужно передать его только очень немногим элементам-потомкам, лучше сохранить состояние в общем предке.
Выводы
Когда дело доходит до использования внешней библиотеки для совместного использования состояния в приложении, нам нужно учитывать несколько важных вещей:
1. Если вы хотите поделиться только глобальными состояниями для всех компонентов, таких как темы или настройки, ContextAPI может быть хорошим решением, потому что эти значения меняются не очень часто.
2. Как я уже говорил ранее, если ваши компоненты перерисовываются очень часто, это не обязательно плохо сказывается на производительности.
3. Если некоторые компоненты перерисовываются слишком часто, и вы можете увидеть снижение производительности, или вам трудно обмениваться состояниями между очень вложенными дочерними элементами, возможно, вам следует рассмотреть возможность использования внешних библиотек управления состоянием для упрощения вашего кода или повышения производительности.
4. Если вам нужно их использовать, не забывайте использовать их экономно и старайтесь не решать все свои проблемы таким образом, потому что могут быть более эффективные решения.
Источник: Bruno Carmine
SUREcrm - свободная CRM-система, созданная с использованием Recoil - используйте бесплатно. Contributors are welcome!