Недавно я посетил семинар по Advanced React, который провел Райан Флоренс из ReactTraining.com. Этот пост - моя лучшая попытка выделить некоторые из самых крутых моментов, о которых он рассказал, хотя я могу почти гарантировать, что не приблизюсь к реальности; Я призываю всех разработчиков React, чтобы ваш босс отправил вас к следующему, который будет в городе. Ты многому научишься, и, я обещаю, получишь от этого массу удовольствия.
React предлагает несколько способов обернуть один компонент другим с целью передачи состояния вниз. В этом посте я рассмотрю все известные мне способы, обсудю с каждым из них некоторые плюсы и минусы и, в конце концов, представлю новый подход: рендеринг обратных вызовов.
Вариант использования
Давайте создадим компонент, который отображает некоторый контент, передавая… текущее время. Менее глупый пример может использовать значения биржевых тикеров, данные геолокации и т. Д.
Идея состоит в том, что я визуализирую этотCurrentTime
компонент с дочерним в нем, и этот дочерний компонент получит текущее время как опору. Компонент текущего времени будет выглядеть примерно так
Конечно, это будет отображать военное время, и не совсем прилично форматировать однозначные числа, но кого это волнует :)
И мы хотим использовать его вот так
В оставшейся части этого поста мы исследуем способы сделать CurrentTime таким, чтобы это работало. Поехали!
Просто клонируйте детей
Самый простой способ - просто клонировать дочерние элементы, переданные в CurrentTime, например
Итак, теперь CurrentTime
просто принимает любой дочерний компонент, который вы ему передаете, и клонирует его с целью передачи дополнительной временной опоры. Это работает, но немного раздувает нашу разметку, а также заставляет нас создавать новый компонент; что-то подобное не сработает
Компонент высшего порядка
Что, если мы можем взять существующий компонент и добавить (не смешивать!) Возможность для него просто автоматически передавать то же самое время пропуска.
Введите компонент более высокого порядка;
Теперь currentTime - это просто функция. Это функция, которая принимает компонент, а затем возвращает НОВЫЙ компонент, единственная задача которого - визуализировать исходный компонент с теми же реквизитами, а также с новым свойством времени.
Если вы видите там декоратор, @currentTime
, обратите внимание, что мы могли бы так же легко сделать что-то вроде
Но я предпочитаю упрощенный синтаксис, который избавляет от необходимости явно задавать промежуточный компонент.
До сих пор неизменным было то, что нам всегда приходилось каждый раз создавать новый компонент; просто рендеринг встроенного div никогда не сработает, потому что у нас не будет возможности добраться до опоры времени. У нас также была некоторая связь с нашей иерархией компонентов: нам всегда нужен компонент, который получает время, чтобы быть дочерним. Посмотрим, сможем ли мы это еще немного упростить.
Рендеринг обратных вызовов
Что, если вместо передачи компонента для дочернего элемента CurrentTime
мы просто передадим функцию. А что, если бы этой функции было передано значение времени. Разве мы не смогли бы достичь того же, но более гибко? Да! Посмотрим, как это выглядит.
Мы визуализировали фактическую функцию как дочерние элементы CurrentTime
. Это дало нам обратный вызов с желаемым значением времени - теперь мы можем делать с этим значением все, что захотим.
Можем ли мы получить лучшее из обоих миров?
Что, если иногда нам нужен такой красивый обратный вызов, а иногда мы просто хотим добавить компонент в качестве дочернего? Просто: поддерживайте детей, как мы делали раньше, но также поддерживайте рендеринг prop в нашем компоненте CurrentTime. Посмотрим, как это выглядит
Итак, теперь CurrentTime
может принимать опору рендеринга, или более традиционный дочерний компонент.
Есть ли минусы?
Использование подобных обратных вызовов для рендеринга контента - это фантастика, но есть ли недостатки? Мне кажется, что если зайти слишком далеко, разработчики могут усложнить себе задачу. Например, при использовании Redux я бы предпочел просто соединять свои компоненты вот так
а затем визуализировать их по мере необходимости, вместо того, чтобы принудительно использовать этот код во встроенных функциях в середине моего JSX. Но ЫММВ. Удачного кодирования!
Если у вас есть какие-либо комментарии, напишите мне в Twitter - система комментариев Medium ужасна.