Propsien välittäminen komponentille
React komponentit käyttävät propseja kommunikoidakseen toistensa välillä. Jokainen pääkomponentti voi välittää tietoa sen lapsikomponenteille antamalla niille propseja. Propsit saattavat muistuttaa HTML attribuuteista, mutta ne voivat välittää mitä tahansa JavaScript arvoa, kuten oliota, listoja ja funktioita.
Tulet oppimaan
- Miten välittää propseja komponentille
- Miten lukea propseja komponentista
- Miten määritellä oletusarvoja propseille
- Miten välittää JSX:ää komponenteille
- Miten propsit muuttuvat ajan kanssa
Tuttuja propseja
Propsit ovat tietoa jota välität JSX tagille. Esimerkiksi className
, src
, alt
, width
ja height
ovat muutamia propseja, joita voit välittää <img>
tagille:
function Avatar() { return ( <img className="avatar" src="https://i.imgur.com/1bX5QH6.jpg" alt="Lin Lanying" width={100} height={100} /> ); } export default function Profile() { return ( <Avatar /> ); }
Propsit joita välität <img>
tagille ovat esimääriteltyjä (ReactDOM mukautuu HTML standardiin). Mutta voit välittää mitä tahansa propseja omalle komponentillesi, kuten <Avatar>
:lle, mukauttaaksesi sen. Tässä miten!
Propsien välittäminen komponentille
Seuraavassa koodissa Profile
komponentti ei välitä yhtään propsia sen Avatar
lapsikomponentille:
export default function Profile() {
return (
<Avatar />
);
}
Voit antaa Avatar
:lle propseja kahdessa vaiheessa.
1. Vaihe: Välitä propsi lapsikomponentille
Ensiksi välitä jokin propsi Avatar
:lle. Esimerkiksi anna sille kaksi propsia: person
(olio) ja size
(numero):
export default function Profile() {
return (
<Avatar
person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
size={100}
/>
);
}
Nyt voit lukea näitä propseja Avatar
komponentin sisällä.
2. Vaihe: Lue propsit lapsikomponentin sisällä
Voit lukea nämä propsit listaamalla niiden nimet person, size
pilkulla eroteltuna ({
and })
sisällä suoraan function Avatar
jälkeen. Näin voit käyttää niitä Avatar
koodin sisällä, kuten käyttäisit muuttujia.
function Avatar({ person, size }) {
// person and size are available here
}
Lisää vähän logiikkaa Avatar
:lle, joka hyödyntää person
ja size
proppeja renderöinnissä, ja olet valmis.
Nyt voit määritellä Avatar
:n renderöimään monella erilaisella tavalla eri propseilla. Kokeile muuttaa arvoja!
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: 'Katsuko Saruhashi', imageId: 'YfeOqp2' }} /> <Avatar size={80} person={{ name: 'Aklilu Lemma', imageId: 'OKS67lh' }} /> <Avatar size={50} person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }} /> </div> ); }
Propsien avulla voit ajatella pää- ja lapsikomponentteja erikseen. Esimerkiksi voit muuttaa person
tai size
propsia Profile
:n sisällä ilman, että täytyy miettiä miten Avatar
käyttää niitä. Samoin voit muuttaa miten Avatar
käyttää näitä propseja ilman, että täytyy katsoa Profile
koodia.
Voit ajatella propseja “säätiminä”, joita voit säätää. Niillä on sama rooli kuin argumenteilla on funktioissa—itse asiassa, propsit ovat ainoa argumentti komponenttiisi! React komponentit hyväksyvät yhden argumentin, props
olion:
function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}
Useimmiten ei tarvitse kirjoittaa koko props
oliota itsessään, vaan voit destrukturoida sen yksittäisiksi propseiksi.
Oletusarvon määrittäminen propsille
Jos haluat antaa propsille oletusarvon johon turvautua kun arvoa ei ole määritelty, voit tehdä sen destrukturoinnissa laittamalla =
ja oletusarvon sen jälkeen:
function Avatar({ person, size = 100 }) {
// ...
}
Nyt jos <Avatar person={...} />
renderöidään ilman size
propsia, size
asetetaan arvoon 100
.
Oletusarvoa käytetään vain jos size
propsi puuttuu tai jos välität size={undefined}
. Mutta jos välität size={null}
tai size={0}
, oletusarvoa ei käytetä.
Propsien välittäminen JSX spread-syntaksilla
Joskus propsien välittäminen käy toistuvaksi:
function Profile({ person, size, isSepia, thickBorder }) {
return (
<div className="card">
<Avatar
person={person}
size={size}
isSepia={isSepia}
thickBorder={thickBorder}
/>
</div>
);
}
Toistuvassa koodissa ei ole mitään väärää-se voi olla luettavempaa. Mutta ajoittain saatat arvostaa ytimekkyyttä. Jotkin komponentit välittävät kaikki niiden propsit niiden lapsikomponenteilleen, kuten tämä Profile
tekee sen Avatar
:lle. Koska se ei itse käytä suoraan yhtään propsia, voi olla järkevää käyttää lyhyttä “spread” syntaksia:
function Profile(props) {
return (
<div className="card">
<Avatar {...props} />
</div>
);
}
Tämä välittää kaikki Profile
:n propsit Avatar
:lle ilman jokaisen nimen listaamista.
Käytä spread-syntaksia hillitysti. Jos käytät sitä jokaisessa komponentissa, jotain on pielessä. Useimmiten se osoittaa, että sinun täytyisi jakaa komponenttisi osiin ja välittää JSX lapsina. Tästä lisää seuraavaksi!
JSX:n välittäminen lapsena
On yleistä upottaa selaimen sisäänrakennettuja tageja toisiinsa:
<div>
<img />
</div>
Joskus haluat upottaa omia komponentteja samalla tavalla:
<Card>
<Avatar />
</Card>
Kun upotat sisältöä JSX tagiin, pääkomponentti vastaanottaa sisällön propsina nimeltään children
. Esimerkiksi Card
komponentti vastaanottaa children
propin, joka sisältää <Avatar />
komponentin ja renderöi sen diviin käärittynä:
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: 'Katsuko Saruhashi', imageId: 'YfeOqp2' }} /> </Card> ); }
Kokeile korvata <Card>
komponentista <Avatar>
jollain tekstillä nähdäksesi miten Card
komponentti voi kääriä mitä vain sisältöä. Sen ei tarvitse “tietää” mitä renderöidään sen sisällä. Näet tätä tapaa käytettävän monissa paikoissa.
Voit ajatella komponenttia, jolla on children
propsi kuin sillä olisi “aukko” joka voidaan “täyttää” sen pääkomponentista mielivaltaisella JSX:llä. Käytät children
propsia usein visuaalisiin wrappereihin: paneeleihin, ruudukkoihin, jne.
Illustrated by Rachel Lee Nabors
Miten prosit muuttuvat ajan kanssa
Clock
komponentti alla vastaanottaa kaksi propsia sen pääkomponentilta: color
ja time
. (Pääkomponentin koodi on jätetty pois koska se käyttää tilaa, johon emme vielä syvenny.)
Kokeile muuttaa väriä valintaruudusta alla:
export default function Clock({ color, time }) { return ( <h1 style={{ color: color }}> {time} </h1> ); }
Tämä esimerkki havainnollistaa, että komponentti voi vastaanottaa erilaisia propseja ajan saatossa. Propsit eivät aina ole staattisia! Tässä time
propsi muuttuu joka sekunti ja color
propsi muuttuu kun valitset toisen värin. Propsit kuvastavat komponentin dataa ajan kuluessa, ei ainoastaan alussa.
Propsit ovat kuitenkin muuttumattomia (engl. immutable). Kun komponentin täytyy muuttaa sen propseja (esimerkiksi vastauksena käyttäjän toimintoon tai uuteen dataan), sen täytyy “kysyä” sen pääkomponentilta antaakseen sille eri propsit-uuden olion! Sen vanhat propsit sitten heitetään pois ja lopulta JavaScript moottori suorittaa roskienkeruun palauttaen niiden käyttämän muistin.
Älä yritä “muuttaa propseja”. Kun sinun täytyy vastata käyttäjän syötteeseen (kuten värin muutokseen), täytyy “asettaa tila”, josta voit oppia lisää lukemalla Tila: Komponentin muisti.
Kertaus
- Välittääksesi propseja, lisää ne JSX:ään kuten tekisit HTML attribuuteilla.
- Lukeaksesi propseja, käytä
function Avatar({ person, size })
destrukturointi -syntaksia. - Voit määritellä oletusarvon kuten
size = 100
, jota käytetään puuttuvissa sekäundefined
propseissa. - Voit välittää kaikki propsit käyttämällä
<Avatar {...props} />
JSX spread syntaksia, mutta älä käytä sitä liikaa! - Sisäkkäinen JSX koodi kuten
<Card><Avatar /></Card>
ilmeneeCard
komponentinchildren
propsina. - Propsit ovat vain-luku snapshotteja ajasta: joka renderillä se vastaanottaa uuden version propseista.
- Et voi muuttaa propseja. Kun tarvitset interaktiivisuutta, käytä tilaa.
Haaste 1 / 3: Erota komponentti
Tämä Gallery
komponentti sisältää samanlaista merkintäkoodia kahdelle profiilille. Luo Profile
komponentti vähentääksesi koodin toistoa. Sinun täytyy päättää mitä propseja välität sille.
import { getImageUrl } from './utils.js'; export default function Gallery() { return ( <div> <h1>Notable Scientists</h1> <section className="profile"> <h2>Maria Skłodowska-Curie</h2> <img className="avatar" src={getImageUrl('szV5sdG')} alt="Maria Skłodowska-Curie" width={70} height={70} /> <ul> <li> <b>Profession: </b> physicist and chemist </li> <li> <b>Awards: 4 </b> (Nobel Prize in Physics, Nobel Prize in Chemistry, Davy Medal, Matteucci Medal) </li> <li> <b>Discovered: </b> polonium (chemical element) </li> </ul> </section> <section className="profile"> <h2>Katsuko Saruhashi</h2> <img className="avatar" src={getImageUrl('YfeOqp2')} alt="Katsuko Saruhashi" width={70} height={70} /> <ul> <li> <b>Profession: </b> geochemist </li> <li> <b>Awards: 2 </b> (Miyake Prize for geochemistry, Tanaka Prize) </li> <li> <b>Discovered: </b> a method for measuring carbon dioxide in seawater </li> </ul> </section> </div> ); }