Перадача пропсаў у кампанент
Для камунікацыі між сабой кампаненты React выкарыстоўваць пропсы. Кожны бацькоўскі кампанент можа перадаваць некаторую інфармацыю даччыным, задаючы ім пропсы. Пропсы падобныя на атрыбуты ў HTML, але ў іх вы можаце перадаваць любыя JavaScript значэнні, уключаючы аб’екты, масівы, функцыі.
You will learn
- Як перадаваць пропсы ў кампанент
- Як атрымліваць пропсы ў кампаненце
- Як задаваць прадвызначаныя значэнні для пропсаў
- Як перадаць JSX у кампанент
- Як пропсы змяняюцца з часам
Знаёмыя пропсы
Пропсы — гэта інфармацыя, што вы перадаяце ў JSX тэг. Напрыклад: className
, src
, alt
, width
, і height
— некаторыя пропсы, якія можна перадаць у <img>
:
function Avatar() { return ( <img className="avatar" src="https://i.imgur.com/1bX5QH6.jpg" alt="Лінь Ланьін" width={100} height={100} /> ); } export default function Profile() { return ( <Avatar /> ); }
Пропсы, якія можна перадаць у тэг <img>
прадвызначаныя (ReactDOM адпавядае стандарту HTML). Але ва ўласныя кампаненты, такія як <Avatar>
, вы можаце перадаваць любыя пропсы, каб іх дапасоўваць. Вось як гэта зрабіць!
Перадача пропсаў у кампаненты
У гэтым кодзе кампанент Profile
не перадае аніводнага пропса свайму даччынаму кампаненту Avatar
:
export default function Profile() {
return (
<Avatar />
);
}
Вы можаце дадаць новыя пропсы для Avatar
у два этапы.
Крок 1: Перадаць пропсы даччынаму кампаненту
Па-першае, перадайце пропсы ў Avatar
. Напрыклад, давайце перададзім два пропсы: person
(аб’ект) і size
(лічба):
export default function Profile() {
return (
<Avatar
person={{ name: 'Лінь Ланьін', imageId: '1bX5QH6' }}
size={100}
/>
);
}
Цяпер вы можаце прачытаць гэтыя пропсы ў кампаненце Avatar
.
Крок 2: прачытайце пропсы ў даччыным кампаненце
Вы можаце прачытаць гэтыя пропсы, пералічыўшы іх назвы person, size
цераз коску ўнутры ({
і })
адразу пасля function Avatar
. Гэта дазволіць вам выкарыстоўваць іх у Avatar, нібы яны пераменныя.
function Avatar({ person, size }) {
// person і size цяпер даступныя тут
}
Нарэшце, дадайце некаторую логіку да Avatar
, скарыстаўшы пропсы person
і size
для рэндэрынгу.
Цяпер з дапамогай пропсаў вы можаце змяняць канфігурацыю Avatar
, каб рэндэрыць яго па-рознаму. Паспрабуйце пагуляцца са значэннямі!
import { getImageUrl } from './utils.js'; function Avatar({ person, size }) { return ( <img className="avatar" src={getImageUrl(person)} alt={person.name} width={size} height={size} /> ); } export default function Profile() { return ( <div> <Avatar size={100} person={{ name: 'Кацуко Сарухасі', imageId: 'YfeOqp2' }} /> <Avatar size={80} person={{ name: 'Аклілу Лема', imageId: 'OKS67lh' }} /> <Avatar size={50} person={{ name: 'Лiнь Ланьін', imageId: '1bX5QH6' }} /> </div> ); }
Пропсы дазваляюць вам успрымаць бацькоўскі і даччыны кампаненты незалежнымі адзін ад аднаго. Напрыклад, вы можаце змяніць пропсы person
ці size
унутры кампанента Profile
нават не задумваючыся аб тым, як кампанент Avatar
іх выкарыстоўвае. Аналагічна, вы можаце змяняць тое, як Avatar
апрацоўвае гэтыя пропсы, не гледзячы на логіку кампанента Profile
.
Вы можаце разглядаць пропсы як «рычажкі», якімі вы можаце рэгуляваць свой кампанент. Яны выконваюць тую ролю, што і аргументы ў функцыі. Да таго ж, пропсы — адзіны аргумент, які перадаецца ў кампанент! Функцыянальны кампанент React прымае толькі адзін кампанент, а іменна аб’ект props
:
function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}
Звычайна вам не будзе патрэбны сам аб’ект props
, прасцей будзе разабраць на асобныя пропсы.
Прадвызначаныя значэнні для пропсаў
Калі вы хочаце задаць прадвызначанае значэнне, якое будзе выкарыстоўвацца, калі пропс не вызначаны, вы можаце дадаць =
і пасля яго прадвызначанае значэнне:
function Avatar({ person, size = 100 }) {
// ...
}
Цяпер, калі <Avatar person={...} />
будзе адрэндэрына без пропса size
, ягоным значэннем будзе 100
.
Прадвызначанае значэнне будзе выкарыстана толькі калі пропс size
адсутнічае, ці калі зададзены як size={undefined}
. Такія варыянты, як size={null}
ці size={0}
не будуць замененыя на прадвызначанае значэнне.
Перадача пропсаў з выкарыстаннем сінтаксіса разгортвання
Часам пропсы пачынаюць шмат паўтарацца:
function Profile({ person, size, isSepia, thickBorder }) {
return (
<div className="card">
<Avatar
person={person}
size={size}
isSepia={isSepia}
thickBorder={thickBorder}
/>
</div>
);
}
Няма нічога дрэннага ў тым, каб паўтараць імёны пропсаў — такі код будзе больш зразумелым. Але магчыма з часам вам захочацца зрабіць яго лаканічней. Некаторыя кампаненты перадаюць свае пропсы даччыным, напрыклад як кампанент Profile
перадае іх кампаненту Avatar
. Так як кампанент не выкарыстоўвае ўласныя пропсы сам, ёсць сэнс скарыстаць больш лаканічны сінтаксіс разгортвання:
function Profile(props) {
return (
<div className="card">
<Avatar {...props} />
</div>
);
}
Гэта перадасць усе пропсы кампанента Profile
кампаненту Avatar
без іх пераліку спісам.
Карыстайцеся аператарам разгортвання разумна. Калі вы пачынаеце выкарыстоўваць яго ў кожным кампаненце, вы штосьці робіце не так. Часта гэта прыкмета таго, што варта раздзяліць кампаненты і перадаць даччыныя ў выглядзе JSX. Далей разгледзім як гэта зрабіць!
Перадача JSX у якасці даччыных элементаў
Звычайная практыка — укладаць у стандартны набор тэгаў іншыя тэгі:
<div>
<img />
</div>
Часам вам можа спатрэбіцца зрабіць тое ж самае і з уласнымі кампанентамі:
<Card>
<Avatar />
</Card>
Калі вы ўкладаеце штосьці ў JSX тэг, бацькоўскі кампанент атрымае кантэнт у якасці пропса пад назвай children
. Напрыклад, кампанент Card
з прыкладу ніжэй атрымае пропс children
, у якім будзе <Avatar />
, і адрэндэрыць яго ўнутры div:
import Avatar from './Avatar.js'; function Card({ children }) { return ( <div className="card"> {children} </div> ); } export default function Profile() { return ( <Card> <Avatar size={100} person={{ name: 'Кацуко Сарухасі', imageId: 'YfeOqp2' }} /> </Card> ); }
Паспрабуйце замяніць <Avatar>
унутры <Card>
на які-небудзь тэкст каб паглядзець як кампанент Card
можа працаваць з розным укладзеным кантэнтам. Яму не трэба «ведаць», што будзе адрэндэрына ўнутры яго. Падобны гібкі шаблон вы яшчэ шмат дзе пабачыце.
Паспрабуйце разгледзіць кампанент з пропсам children
як «дзірку», якую бацькоўскі кампанент можа запоўніць разметкай JSX. Вам часта давядзецца выкарыстоўваць пропс children
для візуальных абгортак: панэлей, сетак і г.д.
Illustrated by Rachel Lee Nabors
Як пропсы змяняюцца з часам
Кампанент Clock
ніжэй атрымлівае два пропсы ад бацькоўскага кампанента: color
і time
(бацькоўскі кампанент не разглядаецца, бо ён выкарыстоўвае стан, у падрабязнасці чаго мы яшчэ не паглыналіся).
Паспрабуйце змяніць колер у прыкладзе ніжэй:
export default function Clock({ color, time }) { return ( <h1 style={{ color: color }}> {time} </h1> ); }
Дадзены прыклад адлюстроўвае, што пропсы, якія кампанент атрымлівае, могуць змяняцца з часам. Пропсы не заўсёды статычныя! Тут, напрыклад, пропс time
змяняецца кожную секунду, а пропс color
змяняецца падчас выбару іншага колеру. Пропсы змяшчаюць даныя кампанента ў канкрэтны момант, а не толькі ў момант першага рэндэру.
Не гледзячы на гэта, пропсы нязменныя — гэты тэрмін азначае аб’ект, які не можа змяняцца пасля стварэння. Калі кампаненту трэба змяніць пропс (напрыклад, у адказ на ўзаемадзеянне з боку карыстальніка ці новыя даныя), яму давядзецца «папрасіць» бацькоўскі кампанент перадаць новы іншы пропс — новаствораны аб’ект! Старыя пропсы будуць адкінутыя, і ў рэшце рэшт рухавік JavaScript выдаліць іх з памяці.
**Не спрабуйце «змяняць пропсы». **Калі вы хочаце адрэагаваць на ўведзеныя карыстальнікам даныя (напрыклад, змену колеру), вам спатрэбіцца «задаць стан». Падрабязней пра гэта вы можаце даведацца на старонцы «Стан: Памяць кампанента.»
Recap
- Каб перадаць пропсы, дадайце іх у JSX як бы вы дадалі атрыбуты ў HTML.
- Каб прачытаць пропсы, скарыстайце дэструктурызацыйны сінтаксіс:
function Avatar({ person, size })
. - Вы можаце задаць прадвызначанае значэнне для пропса:
size = 100
, яно будзе скарыстана, калі пропс адсутнічае ці ягонае значэннеundefined
. - Вы можаце перадаць усе пропсы даччынаму элементу, скарыстаўшы сінтаксіс разгортвання:
<Avatar {...props} />
. Але не выкарыстоўвайце яго зашмат! - Укладзены JSX, такі як
<Card><Avatar /></Card>
, з’явіцца ў кампаненцеCard
у якасці пропсыchildren
. - Пропсы нязменны і адлюстроўваюць толькі цяперашні стан: пры кожны рэндэры кампанент атрымлівае новую версію пропсаў.
- Вы не можаце змяняць пропсы. Калі вам патрэбная інтэрактыўнасць, вам спатрэбіцца задаць стан.
Challenge 1 of 3: Вынесіце кампанент
Дадзены кампанент Gallery
змяшчае вельмі падобную разметку для двух профіляў. Вынесіце яе ў кампанент Profile
, каб паменшыць колькасць кода, які паўтараецца. Вам давядзецца выбраць, якія пропсы вам спатрэбіцца перадаваць.
import { getImageUrl } from './utils.js'; export default function Gallery() { return ( <div> <h1>Выбітныя навукоўцы</h1> <section className="profile"> <h2>Марыя Складоўская-Кюры</h2> <img className="avatar" src={getImageUrl('szV5sdG')} alt="Марыя Складоўская-Кюры" width={70} height={70} /> <ul> <li> <b>Сфера дзейнасці: </b> фізіка і хімія </li> <li> <b>Нагароды: 4 </b> (Нобелеўская прэмія па фізіцы, Нобелеўская прэмія па хіміі, медаль Дэві, медаль Матэуччы) </li> <li> <b>Адкрыццё: </b> Палоній (хімічны элемент) </li> </ul> </section> <section className="profile"> <h2>Кацуко Сарухасі</h2> <img className="avatar" src={getImageUrl('YfeOqp2')} alt="Кацуко Сарухасі" width={70} height={70} /> <ul> <li> <b>Сфера дзейнасці: </b> геахімія </li> <li> <b>Нагароды: 2 </b> (прыз Міякэ па геахіміі, прыз Танака) </li> <li> <b>Адкрыццё: </b> метад вымярэння вуглякіслага газу ў марской вадзе </li> </ul> </section> </div> ); }