Хотя в названии библиотеки React присутствует что-то “РЕАКТивное”, она не является полностью реактивной.
Разберём этот вопрос по порядку.
Что такое реактивное программирование?
Реактивен или нереактивен означает, что React следует принципам реактивного программирования. Поэтому стоит разобраться, в чем его суть.
В реактивном программировании любые данные могут быть представлены в виде асинхронных потоков/стримов (streams), на которые можно подписаться и реагировать на изменения. Любые события DOM, включая обычные клики мыши, являются отличным примером.
Мы можем создавать потоки (стримы) из всего, что угодно, не только из кликов или ховеров. Потоком может быть переменная, ответы из бэкенда, кэш, структуры данных и так далее.
Поток - это последовательность событий, разворачивающихся во времени. Их можно объединять (merge), фильтровать (filter) и преобразовывать в другие потоки (map) с помощью различных функций.
Тот, кто создает событие, называется observer
, а тот, кто получает (слушает) и обрабатывает его - subscriber
.
Можно сравнить YouTube. Мы подписаны на много каналов, которые публикуют свои видео. Каналы - это observers, мы - subscribers. Подписчиков может быть много, и каждый может по-разному обрабатывать события. Например, кто-то поставит лайк, а кто-то просто пропустит.
Главное, что есть поток событий (”креаторы” выкладывают видео), происходящих с течением времени, и мы на него подписаны, чтобы впоследствии обработать эти события.
Реактивное программирование подразумевает реакцию на потоки событий, а не явный запрос какого-то действия от пользователя.
Ключевой момент заключается в том, что количество и время появления событий не контролируются, поэтому программное обеспечение должно быть надежным и масштабируемым для управления изменчивыми нагрузками.
Как работает React?
React основан на рендерах. Рендеры зависят от изменения props
или state
. А изменения props
и state
зависят от внешних асинхронных событий.
Событие вызывает изменение состояния, которое в свою очередь меняет UI.
Внешне выглядит как поток данных, но на самом деле есть один нюанс. Он заключается в том, КАК React обрабатывает события и изменяет UI.
React разделяет обработку событий (events) от обновлений компонентов и изменения UI. Всё это сделано, чтобы оптимизировать изменения DOM элементов. Если мы будем вызывать множество изменений state
друг за другом, то React будет стараться их объединть и произвести меньше UI (DOM) изменений.
Реактивен ли React?
React “планирует” изменения UI. Они могут быть не равны количеству поступающих событий.
Отсюда теряется понятие потоковости и "реактивности". Это очень хорошо заметно, если попробовать реализовать с помощью React приложение, основанное на системе постоянных событий (например, реальновременной графики), которые "пушатся" извне. React, как правило, не так хорошо справляется с данной задачей и требует использования сторонних библиотек.
Команда React также подчеркивает, что не стремится позиционировать библиотеку, как “реактивной”.
Итого, разобравшись в понятии реактивности и в том, как React обрабатывает потоки асинхронных событий, мы пришли к выводу, что он не соответствует этой парадигме полностью.
Top comments (3)
Отличная статья, написанная простым и понятным языком. Доходчиво, с примерами. Буду рекомендовать.
Сперва вы путаете реактивность с программированием потоков данных.
Далее вы путаете паттерны PubSub и Observable
А в конце вообще зачем-то лезете внутрь компонента, обосновывая принадлежность парадигме особенностями внутренней реализации.
По вашей логике, если в pipe`е RxJS есть bufferTime, то поток перестает быть реактивным? Ну дурость же
То есть когда React заботится о производительности и батчит апдейты UI в ответ на часто меняющееся состояние - он перестает быть реактивным?
Суть же в том, что он изменение состояния переводит в изменения на UI. State/context обновился - приложение перерисовалось - изменения отобразились. Сами.
так никто и не контроллирует то как часто state/context меняются