Передача пропсов компоненту
Компоненты React общаются друг с другом с помощьюпропсов. Каждый родительский компонент может передать некоторую информацию своим дочерним компонентам, передавая им пропсы. Пропсы могут напомнить вам HTML-атрибуты, но через них можно передавать любые значения JavaScript, включая объекты, массивы и функции.
Вы узнаете
- Как передавать пропсы компоненту
- Как читать пропсы в компоненте
- Как задавать значения по умолчанию для пропсов
- Как передать JSX компоненту
- Как пропсы изменяются со временем
Знакомые пропсы
Пропсы — это информация, которую вы передаёте в JSX-тег. Например,className,src,alt,width и height— это некоторые из пропсов, которые можно передать в тег<img>:
Пропсы, которые можно передать в тег<img>, предопределены (ReactDOM соответствуетстандарту HTML). Но вы можете передавать любые пропсысвоим собственнымкомпонентам, таким как<Avatar>, чтобы настраивать их. Вот как это сделать!
Передача пропсов компоненту
В этом коде компонентProfileне передаёт никаких пропсов своему дочернему компонентуAvatar:
Вы можете передатьAvatarнекоторые пропсы в два шага.
Шаг 1: Передача пропсов дочернему компоненту
Сначала передайте некоторые пропсы вAvatar. Например, давайте передадим два пропса:person(объект) иsize(число):
Примечание
Если двойные фигурные скобки послеperson=сбивают с толку, вспомните, чтоэто просто объектвнутри JSX-фигурных скобок.
Теперь вы можете читать эти пропсы внутри компонентаAvatar.
Шаг 2: Чтение пропсов внутри дочернего компонента
Вы можете прочитать эти пропсы, перечислив их именаperson, sizeчерез запятую внутри({ и })сразу послеfunction Avatar. Это позволяет использовать их внутри кодаAvatar, как если бы это были переменные.
Добавьте некоторую логику вAvatar, которая использует пропсыperson и sizeдля рендеринга, и всё готово.
Теперь вы можете настраиватьAvatarдля рендеринга множеством разных способов с разными пропсами. Попробуйте изменить значения!
Пропсы позволяют вам независимо думать о родительских и дочерних компонентах. Например, вы можете изменить пропсыpersonилиsizeвнутриProfile, не задумываясь о том, какAvatarих использует. Точно так же вы можете изменить способ использования этих пропсов вAvatar, не заглядывая вProfile.
Можно представить пропсы как «ручки настройки», которые можно регулировать. Они выполняют ту же роль, что и аргументы для функций — фактически, пропсыявляютсяединственным аргументом вашего компонента! Функции компонентов React принимают один аргумент — объектprops:
Обычно вам не нужен весь объектpropsцеликом, поэтому вы деструктурируете его на отдельные пропсы.
Подводный камень
Не пропустите пару фигурных скобок{ и }внутри( и )при объявлении пропсов:
Этот синтаксис называется«деструктуризацией»и эквивалентен чтению свойств из параметра функции:
Указание значения по умолчанию для пропса
Если вы хотите задать пропсу значение по умолчанию, которое будет использоваться, когда значение не указано, вы можете сделать это при деструктуризации, поставив=и значение по умолчанию сразу после параметра:
Теперь, если<Avatar person={...} />рендерится без пропсаsize, sizeбудет установлен в100.
Значение по умолчанию используется только если пропсsizeотсутствует или если вы передаётеsize={undefined}. Но если вы передадитеsize={null}илиsize={0}, значение по умолчаниюнебудет использовано.
Передача пропсов с помощью синтаксиса spread в JSX
Иногда передача пропсов становится очень повторяющейся:
В повторяющемся коде нет ничего плохого — он может быть более читаемым. Но иногда вы можете ценить краткость. Некоторые компоненты передают все свои пропсы своим дочерним элементам, как это делаетProfile с Avatar. Поскольку они не используют свои пропсы напрямую, может иметь смысл использовать более краткий синтаксис «spread»:
Это передаёт все пропсыProfile в Avatarбез перечисления каждого из их имён.
Используйте синтаксис spread с осторожностью.Если вы используете его в каждом втором компоненте, что-то не так. Часто это указывает на то, что вам следует разделить ваши компоненты и передавать дочерние элементы как JSX. Подробнее об этом далее!
Передача JSX как дочерних элементов
Обычно встроенные теги браузера вкладываются друг в друга:
Иногда вам захочется вкладывать свои собственные компоненты таким же образом:
Когда вы вкладываете контент внутрь JSX-тега, родительский компонент получает этот контент в пропсе под названиемchildren. Например, компонентCardниже получит пропсchildrenсо значением<Avatar />и отрендерит его внутри обёрточного div:
Попробуйте заменить<Avatar>внутри<Card>на какой-нибудь текст, чтобы увидеть, как компонентCardможет оборачивать любой вложенный контент. Ему не нужно «знать», что рендерится внутри. Вы увидите этот гибкий паттерн во многих местах.
Можно представить компонент с пропсомchildrenкак имеющий «дырку», которую родительские компоненты могут «заполнить» произвольным JSX. Вы часто будете использовать пропсchildrenдля визуальных обёрток: панелей, сеток и т.д.

Иллюстрация отRachel Lee Nabors
Как пропсы меняются со временем
КомпонентClockниже получает два пропса от своего родительского компонента:color и time. (Код родительского компонента опущен, потому что он используетсостояние, в которое мы пока не будем углубляться.)
Попробуйте изменить цвет в выпадающем списке ниже:
Этот пример иллюстрирует, чтокомпонент может получать разные пропсы с течением времени.Пропсы не всегда статичны! Здесь пропсtimeменяется каждую секунду, а пропсcolorменяется, когда вы выбираете другой цвет. Пропсы отражают данные компонента в любой момент времени, а не только в начале.
Однако пропсы являютсяиммутабельными— термин из компьютерных наук, означающий «неизменяемые». Когда компоненту нужно изменить свои пропсы (например, в ответ на взаимодействие пользователя или новые данные), ему придётся «попросить» свой родительский компонент передать емудругие пропсы— новый объект! Его старые пропсы будут затем отброшены, и в конечном итоге механизм JavaScript освободит занимаемую ими память.
Не пытайтесь «изменять пропсы».Когда вам нужно реагировать на ввод пользователя (например, изменение выбранного цвета), вам потребуется «установить состояние», о чём вы можете узнать в разделеСостояние: память компонента.
Резюме
- Чтобы передать пропсы, добавьте их в JSX, как вы бы сделали с атрибутами HTML.
- Чтобы прочитать пропсы, используйте синтаксис деструктуризации
function Avatar({ person, size }). - Вы можете указать значение по умолчанию, например
size = 100, которое используется для отсутствующих иundefinedпропсов. - Вы можете передать все пропсы с помощью JSX-синтаксиса расширения
<Avatar {...props} />, но не злоупотребляйте им! - Вложенный JSX, такой как
<Card><Avatar /></Card>, будет отображаться как пропсchildrenкомпонентаCard. - Пропсы — это доступные только для чтения снимки во времени: каждый рендер получает новую версию пропсов.
- Вы не можете изменять пропсы. Когда вам нужна интерактивность, вам потребуется установить состояние.
Try out some challenges
Challenge 1 of 3:Extract a component #
This Gallery component contains some very similar markup for two profiles. Extract a Profile component out of it to reduce the duplication. You’ll need to choose what props to pass to it.
