Передача параметров¶
Компоненты React используют props для взаимодействия друг с другом. Каждый родительский компонент может передавать некоторую информацию своим дочерним компонентам, передавая им параметры. Параметры могут напомнить вам атрибуты HTML, но через них можно передавать любые значения JavaScript, включая объекты, массивы и функции.
Вы узнаете
- Как передать параметры компоненту
- Как читать параметры из компонента
- Как указать значения по умолчанию для параметров
- Как передать некоторый JSX в компонент
- Как параметры изменяются со временем
Известные параметры¶
Параметры - это информация, которую вы передаете в тег JSX. Например, className, src, alt, width и height - вот некоторые из параметров, которые вы можете передать тегу <img>:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Параметры, которые вы можете передать тегу <img>, предопределены (ReactDOM соответствует стандарту HTML). Но вы можете передавать любые параметры своим компонентам, таким как <Avatar>, чтобы настроить их. Вот как!
Передача параметров компоненту¶
В этом коде компонент Profile не передает никаких параметров своему дочернему компоненту Avatar:
1 2 3 | |
Вы можете передать Avatar некоторые параметры в два этапа.
Шаг 1: Передайте параметры дочернему компоненту¶
Сначала передайте Avatar некоторые параметры. Например, передадим два параметра: person (объект) и size (число):
1 2 3 4 5 6 7 8 9 10 11 | |
Если двойные фигурные скобки после person= вас смущают, вспомните они просто объект внутри JSX-скобок.
Теперь вы можете прочитать эти параметры внутри компонента Avatar.
Шаг 2: Чтение параметров внутри дочернего компонента¶
Вы можете прочитать эти параметры, перечислив их имена person, size, разделенные запятыми внутри ({ и }) непосредственно после функции Avatar. Это позволит вам использовать их внутри кода Avatar, как вы бы сделали это с переменной.
1 2 3 | |
Добавьте в Avatar логику, которая использует параметры person и Size для рендеринга, и все готово.
Теперь вы можете настроить Avatar для рендеринга различными способами с различными параметрами. Попробуйте настроить значения!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | |
1 2 3 4 5 6 7 8 | |
Параметры позволяют вам думать о родительских и дочерних компонентах независимо друг от друга. Например, вы можете изменить параметры person или Size внутри Profile без необходимости думать о том, как Avatar использует их. Аналогично, вы можете изменить, как Avatar использует эти параметры, не заглядывая в Profile.
Вы можете думать о параметрах как о "ручках", которые можно регулировать. Они выполняют ту же роль, что и аргументы для функций - фактически, параметр является единственным аргументом вашего компонента! Функции компонентов React принимают единственный аргумент - объект props:
1 2 3 4 5 | |
Обычно вам не нужен весь объект props, поэтому вы деструктурируете его на отдельные параметры.
Внимание
Не пропустите пару символов { и } внутри ( и ) при объявлении параметров:
1 2 3 | |
Этот синтаксис называется "деструктуризация" и эквивалентен чтению свойств из параметра функции:
1 2 3 4 5 | |
Указание значения по умолчанию для параметра¶
Если вы хотите задать значение по умолчанию для параметра, когда значение не указано, вы можете сделать это с помощью деструктуризации, поместив = и значение по умолчанию сразу после параметра:
1 2 3 | |
Теперь, если <Avatar person={...} /> отображается без свойства size, то size будет установлен в 100.
Значение по умолчанию используется только в том случае, если параметр size отсутствует или если вы передали size={undefined}. Но если вы передадите size={null} или size={0}, значение по умолчанию не будет использоваться.
Пересылка параметров с синтаксисом JSX spread¶
Иногда передача параметров становится очень повторяющейся:
1 2 3 4 5 6 7 8 9 10 11 12 | |
Нет ничего плохого в повторяющемся коде - он может быть более разборчивым. Но иногда вам может быть важна краткость. Некоторые компоненты передают все свои параметры своим дочерним компонентам, например, как этот Profile делает это с Avatar. Поскольку они не используют параметры напрямую, имеет смысл использовать более лаконичный spread-синтаксис:
1 2 3 4 5 6 7 | |
Это пересылает все параметры Profile в Avatar без перечисления имен каждого из них.
Используйте синтаксис распространения сдержанно. Если вы используете его в каждом втором компоненте, что-то не так. Часто это указывает на то, что вам следует разделить ваши компоненты и передавать дочерние компоненты как JSX. Подробнее об этом далее!
Передача JSX в качестве дочерних компонентов¶
Часто встречается вложение встроенных тегов браузера:
1 2 3 | |
Иногда вы захотите вложить свои собственные компоненты таким же образом:
1 2 3 | |
Когда вы вложите содержимое в JSX-тег, родительский компонент получит это содержимое в свойстве children. Например, компонент Card ниже получит параметр children, установленный в <Avatar />, и отобразит его в обертке div:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
1 2 3 4 5 6 7 8 | |
Попробуйте заменить <Avatar> внутри <Card> каким-нибудь текстом, чтобы увидеть, как компонент Card может обернуть любое вложенное содержимое. Ему не нужно "знать", что отображается внутри него. Вы увидите этот гибкий шаблон во многих местах.
Вы можете думать о компоненте с параметром children как о компоненте с "дырой", которая может быть "заполнена" его родительскими компонентами с помощью произвольного JSX. Вы часто будете использовать параметр children для визуальных оберток: панелей, сеток и т. д.
Как параметры меняются со временем¶
Компонент Clock ниже получает два параметра от своего родительского компонента: color и time. (Код родительского компонента опущен, поскольку он использует state, в который мы пока не будем углубляться).
Попробуйте изменить цвет в поле выбора ниже:
1 2 3 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
Этот пример иллюстрирует, что компонент может получать различные параметры с течением времени. параметры не всегда статичны! Здесь параметр time меняется каждую секунду, а параметр color меняется, когда вы выбираете другой цвет. параметры отражают данные компонента в любой момент времени, а не только в начале.
Однако параметры являются иммутабельными- термин из информатики, означающий "неизменный". Когда компоненту нужно изменить свой параметр (например, в ответ на взаимодействие с пользователем или новые данные), он должен "попросить" свой родительский компонент передать ему другой параметр - новый объект! Его старые параметры будут отброшены, и в конечном итоге движок JavaScript вернет память, занятую ими.
Не пытайтесь "менять параметры". Когда вам нужно отреагировать на ввод пользователя (например, изменить выбранный цвет), вам нужно будет "установить состояние", о котором вы можете узнать в Состояние: Память компонента.
Итоги
- Чтобы передать параметры, добавьте их в JSX, точно так же, как это делается с атрибутами HTML.
- Чтобы прочитать параметр, используйте синтаксис деструктуризации
function Avatar({ person, size }). - Вы можете указать значение по умолчанию, например
size = 100, которое используется для отсутствующих инеопределенныхпараметров. - Вы можете переслать все параметры с помощью
<Avatar {...props} />Синтаксис распространения JSX, но не злоупотребляйте им! - Вложенные JSX типа
<Card><Avatar /></Card>будут отображаться какдочерниепараметры компонентаCard. - параметры - это снимки времени, доступные только для чтения: каждый рендер получает новую версию параметра.
- Вы не можете изменять параметры. Когда вам понадобится интерактивность, вам нужно будет установить состояние.
Задачи¶
1. Извлечение компонента¶
Этот компонент Gallery содержит очень похожую разметку для двух профилей. Извлеките из него компонент Profile, чтобы уменьшить дублирование. Вам нужно будет выбрать, какие параметры передать ему.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | |
1 2 3 | |
Показать подсказку
Начните с извлечения разметки для одного из ученых. Затем найдите части, которые не соответствуют ему во втором примере, и сделайте их настраиваемыми с помощью параметров.
Показать решение
В этом решении компонент Profile принимает несколько параметров: imageId (строка), name (строка), profession (строка), awards (массив строк), discovery (строка) и imageSize (число).
Обратите внимание, что параметр imageSize имеет значение по умолчанию, поэтому мы не передаем его компоненту.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | |
1 2 3 | |
Обратите внимание, что вам не нужен отдельный параметр awardCount, если awards - это массив. Тогда вы можете использовать awards.length для подсчета количества наград. Помните, что параметр может принимать любые значения, в том числе и массивы тоже!
Другое решение, более похожее на предыдущие примеры на этой странице, заключается в том, чтобы сгруппировать всю информацию о человеке в одном объекте и передать этот объект как один параметр:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | |
1 2 3 4 5 6 7 8 | |
Хотя синтаксис выглядит несколько иначе, поскольку вы описываете свойства объекта JavaScript, а не коллекцию атрибутов JSX, эти примеры в основном эквивалентны, и вы можете выбрать любой подход.
2. Настройте размер изображения на основе параметров¶
В этом примере Avatar получает числовой параметр size, который определяет ширину и высоту <img>. В данном примере параметр size установлен на 40. Однако если вы откроете изображение в новой вкладке, вы заметите, что само изображение больше (160 пикселей). Реальный размер изображения определяется тем, какой размер миниатюры вы запрашиваете.
Измените компонент Avatar, чтобы он запрашивал наиболее близкий размер изображения на основе параметра size. В частности, если size меньше 90, передавайте 's' ("small"), а не 'b' ("big") в функцию getImageUrl. Проверьте, что ваши изменения работают, отобразив аватары с разными значениями параметра size и открыв изображения в новой вкладке.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
1 2 3 4 5 6 7 8 | |
Показать решение
Вот как вы можете поступить:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | |
1 2 3 4 5 6 7 8 | |
Вы также можете показать более четкое изображение для экранов с высоким DPI, принимая во внимание window.devicePixelRatio:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | |
1 2 3 4 5 6 7 8 | |
Параметры позволяют инкапсулировать подобную логику внутри компонента Avatar (и изменить ее позже, если потребуется), чтобы каждый мог использовать компонент <Avatar>, не задумываясь о том, как запрашиваются и изменяются размеры изображений.
3. Передача JSX в children параметр¶
Извлеките компонент Card из приведенной ниже разметки и используйте параметр children для передачи ему различных JSX:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
Показать подсказку
Любой JSX, который вы поместите внутрь тега компонента, будет передан в качестве параметра children этому компоненту.
Показать решение
Вот как вы можете использовать компонент Card в обоих местах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | |
Вы также можете сделать title отдельным параметром, если хотите, чтобы каждая Card всегда имела заголовок:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | |
Источник — https://react.dev/learn/passing-props-to-a-component
