React Context - не лучшее решение для глобального управления состоянием

React Context был представлен некоторое время назад, но получил распространение только после того, как React Hooks были развернуты с React 16.8. Хотя Context действительно решает проблему, для решения которой он был разработан, это не подходящее решение для глобального управления состоянием по следующим причинам.
Очень сложно отлаживать
На скриншоте выше вы видите расширение Redux Devtools. Он позволяет детально изучить каждое действие, предлагает различие и полное представление о состоянии, а также может перематывать действия, чтобы проверить, что пошло не так.
Это Redux Logger, еще один инструмент отладки на случай, если Redux DevTools окажется недостаточно или неприменим к вашей среде. Он будет регистрировать каждое отправленное действие и показывать вам состояние до и после его применения. Однако Redux Logger не может перематывать. Но он по-прежнему может делать больше, чем любой другой инструмент для определения контекста.
Это React Context DevTool. Он позволяет вам просматривать состояние контекста - и все. Также есть представление различий, но непонятно, как это работает, если не отправляются действия. Я добавлю, что это проект на ранней стадии, и над ним работают только два участника. Итак, хотя инструмент впечатляет, и я благодарен его разработчикам, он еще не на очень полезной стадии.
Вы также можете использовать React DevTools, но они работают не во всех средах и по-прежнему не имеют большинства функций Redux DevTools. Также есть способ связать контекст с Redux DevTools, но, учитывая сложность этого решения, я бы просто использовал Redux.
Это не может быть продлено
Одна из самых мощных функций Redux - это усилители. Одним из наиболее часто используемых расширений является промежуточное программное обеспечение, которое позволяет вам переопределить функцию dispatch. Возможно, вы использовали такое промежуточное ПО в своих проектах, как redux-thunk, redux-logger, redux-saga и т. Д. Вы также можете написать собственное промежуточное ПО для встраивания логики непосредственно в хранилище, уменьшая количество шаблонов и повторений.
React Context не предлагает таких интерфейсов. Вы можете либо встроить эту логику в другое место (компоненты / помощники), либо использовать ловушку useReducer и вручную обернуть функцию dispatch. Но даже тогда он не сможет реализовать половину того, что могут улучшить усилители Redux.
Это не отделяет логику от презентации
Это продолжение предыдущего аргумента. Поскольку нет возможности встроить настраиваемое поведение в Context, вы должны делать это в своих компонентах. Теперь вы начинаете смешивать логику и представление в одних и тех же сущностях. Конечно, вы можете разделить свои компоненты на контейнер компоненты и тупые компоненты, но действительно ли это сработало для кого-нибудь?
С помощью Redux и промежуточного программного обеспечения, такого как Thunk или Saga, вы можете описать свою бизнес-логику внутри создателей действий и / или настраиваемых промежуточных программ. Это позволяет использовать только тупые компоненты и четко разделить бизнес-логику и представление.
Это медленно
Да, это так. React Context медленный, период. Это потому, что здесь нет механизма выбора, как в Redux. Это означает, что при изменении любого значения в контексте каждый компонент, который использует этот контекст, будет повторно отрисован, независимо от того, использует ли он его на самом деле. Частично его можно смягчить с помощью React.memo.
С другой стороны, у Redux такой проблемы нет. И с HOS, и с Hooks вы точно определяете, какие данные вам нужны, и ваш компонент будет повторно отображать только тогда, когда эти данные изменятся. Это означает, что вам не нужны React.memo ненужные звонки.
Это не короче и не легче
Один из аргументов в пользу Context, который вы часто слышите, заключается в том, что он короче или проще, чем Redux. Что ж, давай проверим.
Я написал для вас четыре примера: использование Context, использование Context + useReducer, Redux и Redux + Redux Toolkit:
Предполагается, что компоненты и логика состояния находятся в отдельных файлах, но я опускал это для простоты. Вы можете видеть, что примеры с Redux не длиннее, чем контекстные. Более того, вам нужно только одно состояние Redux в вашем приложении (и использовать срезы для создания подсостояний), но вам, вероятно, понадобится более одного контекста, что приведет к двойному шаблону.
Заключительные примечания
Конечно, всегда есть варианты использования React Context. Он идеально подходит для хранения параметров темы, локальных настроек и других свойств, которые не часто меняются. Но если вы начнете с Context, и ваше приложение будет расти и усложняться, вам придется потратить время на переписывание Context в Redux из-за проблем с удобочитаемостью и производительностью.
Спасибо за чтение, надеюсь, вам понравилась эта статья. Дайте мне знать в комментариях, что вы думаете о дихотомии Context и Redux!