Давайте углубимся в мир чистого React-кода со сложными компонентами.
После реализации своего первого сложного компонента в React я стал буквально зависим от этого шаблона. Как провозглашённый эксперт по этому вопросу (на самом деле я учился благодаря Райану Флоренсу и его речи о сложных компонентах) я собираюсь в пару шагов научить вас одному из самых продвинутых шаблонов в React. Почему? Потому что вы заслуживаете лучший код!
Возможно, на этой строчке вы уже думаете, а кто этот парень? Это же не Кент Доддс, который написал курс по сложным компонентам. Также он не обожаемый нами проповедник React Дэн Абрамов. И моим ответом будет — вы правы!
Танцующая лошадь “Вы правы” для каждого!
Всё правильно, вы меня ещё не знаете. Но на случай, если вы хотите знать, меня зовут Стивен. Вы можете подписаться на меня в Twitter. Но пока что я всё ещё никто, а значит, если вы заинтересованы в сложных компонентах, это руководство для вас.
Сложные компоненты оставляют вашу JSX-разметку чистой. Вы можете полностью сфокусироваться на отображаемой части, в то время как логика будет скрыта внутри компонентов. Когда я первый раз писал сложный компонент моя часовая сессия кодирования превратилась в целую ночь. Я не смог устоять перед тем, чтобы переписать весь код своего стороннего проекта. За эти 6 часов я создал мысленный путеводитель, который поможет вам в разработке ваших компонентов. И, что лучше всего, я здесь для того, чтобы поделиться им с вами и сделать ваш код счастливым.
3-шаговый путеводитель для сложных компонентов
Окей, время для вашего вздорного свободного руководства написать пару сложных компонентов. Сегодня вы собираетесь создать многоэтапный мастер форм. Как только вы закончите, у вас будет чистый, многоразовый мастер форм, который вы сможете использовать в любом React-проекте.
Когда вы работаете со сложными компонентами, вы должны помнить, что этот шаблон полностью о программной передаче props, как однажды сказал Райан Флоренс. Если вы не испытываете проблем с понимаем этой концепции, то дальнейшее изучение должно пройти гладко.
Шаг 1. Выделите свою JSX-разметку
Для начала сделайте вашу JSX-разметку более простой для чтения сгруппировав связанные элементы. Этот способ расширяем, так как добавление другого шага или кнопки так же просто, как добавление нового компонента для релевантной группы компонентов. Логика, которая управляет фундаментальными компонентами внизу, будет поступать от компонентов выше. StepList и ButtonList создают первый уровень связанных компонентов.
Step отображает полученный компонент, если это активный шаг. Previous возвращает на шаг назад, если возможно. Next двигает дальше, если возможно. Submit отображает подтверждённое сообщение, но только если этот шаг последний. StepList и ButtonList передают props, чтобы определить, какие кнопки отобразить на текущем шаге и какой шаг активный.
Шаг 2. Определите, какие props понадобятся вашим компонентам
Здесь вы должны подумать о том, какие props нужны каждому контейнеру компонента. StepList’у нужно знать текущий шаг, чтобы делать вывод для пользователя. Используйте prop текущего шага. ButtonList показывает кнопки Previous, Next, и Submit на некоторых шагах.. Активный шаг и общее количество шагов помогают определить, когда показывать каждую из кнопок. Вам нужно подтвердить функцию, так как это форма. Теперь, когда у вас есть props, вы закончили. Ну, не совсем.
Держа в голове ваши props вы, возможно, попытались передать их напрямую к вашим компонентам, как вы видите на картинке выше, но есть более чистый способ передать props. Лучший способ передать ваши props косвенно. Вы спросите как? React API имеет пару полезных методов, которые вы можете использовать для создания новых компонентов из уже существующих. Здесь на помощь придут React.Children и React.cloneElement.
Шаг 3. Свяжите ваши компоненты с React API
Лучшая часть React в том, что все компоненты являются обычными объектами. Как и с любым объектом, вы можете управлять ими для передачи различных props и функций без необходимости править JSX-компоненты напрямую. React.Children позволит вам перебирать дочерние элементы компонента. React.cloneElement позволит вам создать новый компонент с дополнительными props из уже существующего элемента компонента.
Здесь вы перебираете дочерние элементы в FormWizard с помощью React.Children. С каждым шагом используйте React.cloneElement для создания нового компонента с желаемыми props, которые вы хотите передать дальше по дереву компонентов.
Функции продвижения, onNextStep и onPreviousStep,используются кнопками Next и Previous. Submit использует handleSubmit. Мы передаём эти props новому компоненту ButtonList, чтобы передать их дальше. prop activeStepIndex помогает определить, нужно ли отобразиться step-компонентам или кнопкам формы.
Новый компонент Step получит prop isActive от StepList, чтобы узнать, когда отображать шаг. Функции и props состояния в компоненте ButtonList передаются соответствующим кнопкам, которые в них нуждаются. Наша форма прячет кнопку возвращения на первом шагу, кнопку дальше на последнем, а также отображает кнопку подтверждения на последнем шаге. В других случаях кнопки видны.
Наконец, используйте переданные props для того, чтобы определить, что должно быть отражено. Как видите, очень просто! Ну, почти. Я согласен, что некоторые вещи всё-таки нужно обмозговать. Но вот лучшая часть: Опра и Я — оба водолей по знаку зодиака (как водолей во множественном числе? Водолеи?), а значит вы получаете демо, вы получаете демо, все получают демо! Вот демо этого урока.
С React 16.3 вы можете использовать Context API для того, чтобы сделать FormWizard ещё более гибким в отношении props. Поскольку ваше приложение только имеет только несколько уровней, вам лучше следовать советам в этих документах. Используйте Context, когда вы передаёте одни и те же данные многим компонентам на многих уровнях.
Перевод статьи Steven Natera: 3 easy steps to writing compound components.