Комментарии 16
Отдельно Field всё равно экспортировать надо, потому что он может быть вынесен в отдельный файл, где Form не нуєжен
import Field from './field'
лучше использовать import { Field } from './Field'
. Иначе готовьтесь к Fild / Feld и т.п. переменным по недосмотру.Контексты работают достаточно изолированно для большинства кейсов. Вложенные провайдеры одного контекста образуют стэк значений, невложенные — параллельные стэки: https://codesandbox.io/s/quirky-hill-txjny
Вроде нет способа получить внутри провайдера данные того же контекста его родителей или соседей
C хуком более компакто, ну и небольшой "хак" с провайдером https://codesandbox.io/s/thirsty-lake-36kd8 :)
P.S. исправил уже без HOC, там оказывается все намного проще если посмотреть в документацию))
Один раз — не… Я тоже не фанат, но нам или так, или оборачивать классы в примитивные HOC, или громоздкие консьюмеры. На практике HOC предпочту, если какие-то универсальные провайдеры, а по мелочи — hook
Типа вот так codesandbox.io/embed/nice-hooks-wui5t
Вроде как удобно, всё в кучке. Любой компонент, на любом уровне вложенности (только в HOC его обернуть), имеет доступ к любому контексту. Или всё же желательно провайдер держать как можно ближе только к общим потребетилям?
Абсолютно все во многих случаях не получится в принципе из-за стэковой природы контекстов. Вот тот же подход к формам, описанный в посте (используется во многих библиотеках реакт-компонентов для работы с формами): сложновато будет, как минимум, пробросить в контекст все данные для всех форм приложения за один раз.
Ну а так общие соображения: если данные какие-то нужны только одному компоненту внутри, то смысла нет вообще контекст создавать. Если контекст всё же нужен, данные надо шарить между компонентами и пробрасывать их по дереву не хочется, но только например, в одном роуте приложения, то только его и обернуть.
Минусы по факту есть: ресурсы контексты потребляют, конечно больше, чем проброс свойств на один уровень, но если не создавать их тысячами, то вряд ли заметите. Тут больше не про ресурсы, а про поддержку. Глобальные контексты — по сути те же глобальные переменные со всеми вытекающими, особенно если прокидывают методы для изменения своего состояния.
На практике на уровне приложения больше 5 провайдеров на уровне всего приложения создавать не приходилось: глобальные роуты, глобальный стор, темизация, авторизация, логирование или типа того. Может ещё 1 или 2, но больше ничего вспомнить не получается, хотя сейчас одна задача есть — может быть внедрим через контекст Di-контейнер или сервис-локатор, чтобы избавиться от импортов, как минимум, конкретных объектов сервисов. Но ещё исследования не закончили.
но если не создавать их тысячами
если данные какие-то нужны только одному компоненту внутри, то смысла нет вообще контекст создавать.
На практике на уровне приложения больше 5 провайдеров на уровне всего приложения создавать не приходилось: глобальные роуты, глобальный стор, темизация, авторизация, логирование или типа того.
Да, всё так. Контексты создаю и разделяю по фичам, которые размазаны по всему приложению. А локальные фичи — соответственно в стейте умного компонента этой фичи. Другое дело, что нужно поймать момент, когда фича перестаёт быть локальной, и её нужно выносить в контекст..)
Глобальные контексты — по сути те же глобальные переменные
Этот вопрос решаю именованием контекста именем фичи, за которую он отвечает.
Пишем API для React компонентов, часть 6: создаем связь между компонентами