Komponensek és prop-ok
A komponensek lehetővé teszik számodra a felhasználói felület független, újrafelhasználható darabokra való felosztását, és segítenek hogy minden darabról a többitől elzártan tudj gondolkodni. Ez az oldal a komponensek lényegét mutatja be. A részletes komponens API referenciát itt találod.
Elviekben a komponensek olyanok mint a JavaScript függvények. Egy tetszőleges számú inputot fogadnak (amiket “prop”-oknak hívunk) és egy React elemet adnak vissza ami leírja mi jelenjen meg a képernyőn.
Függvény és Osztály komponensek
Egy komponens legegyszerűbb definiálásának módja egy JavaScript függvény:
function Welcome(props) {
return <h1>Helló, {props.name}</h1>;
}
Ez a függvény egy érvényes React komponens, mivel egyetlen “props” (angol properties, vagy tulajdonságok) objektum argumentuma van ami adatot tartalmaz, és egy React elemet ad vissza. Egy ilyen komponenst hívunk “függvény komponensnek”, mert szó szerint csak egy JavaScript függvény.
Emellett használhatsz ES6 osztályokat is komponensek definiálásához:
class Welcome extends React.Component {
render() {
return <h1>Helló, {this.props.name}</h1>;
}
}
A React szemszögéből a fenti két komponens egymással megegyező.
Mind a függvény-, és osztálykomponensek rendelkeznek néhány extra funkcióval, amit a következő fejezetekben beszélünk meg.
Egy komponens renderelése
Korábban csak olyan React elemekkel találkoztunk, amik csak DOM címkéket képviseltek:
const element = <div />;
Azonban az elemek képviselhetnek a felhasználó által definiált komponenseket is:
const element = <Welcome name="Sára" />;
Ha a React egy olyan elemet lát, ami egy felhasználó által definiált komponenst képvisel, akkor a JSX attribútumokat és a gyermekeket egy sima objektumként küldi le a komponensnek. Ezt az objektumot hívjuk “props”-nak.
Például ez a kód a “Helló, Sára” szöveget rendereli az oldalon:
function Welcome(props) { return <h1>Helló, {props.name}</h1>;
}
const element = <Welcome name="Sára" />;ReactDOM.render(
element,
document.getElementById('root')
);
Foglaljuk össze mi történik ebben a példában:
- Meghívjuk a
ReactDOM.render()
metódust a<Welcome name="Sára" />
elemmel. - A React meghívja a
Welcome
komponenst a{name: 'Sára'}
props objektummal. - A
Welcome
komponensünk visszaadja a<h1>Helló, Sára</h1>
elemet eredményként. - A React DOM hatékonyan frissíti a DOM-ot hogy az megegyezzen a
<h1>Helló, Sára</h1>
-val.
Megjegyzés: A komponensek neveit mindig nagybetűvel kezdd.
Azokat a komponenseket amik kisbetűvel kezdődnek, a React szimpla DOM címkékként kezeli. Például a
<div />
egy HTML div címkét képvisel, de a<Welcome />
egy komponenst, és szükséges, hogy aWelcome
a hatókörben legyen.Ha többet szeretnél megtudni ezen közös megegyezés mögötti érvelésről, olvasd el a JSX-ről mélyebben részt.
Komponensek komponálása
A komponensek utalhatnak más komponensekre is a kimenetükben. Ez lehetővé teszi számunkra, hogy ugyanazt a komponens absztrakciót használjuk bármilyen részletességgel. Egy gomb, egy űrlap, egy dialógus, egy képernyő: React alkalmazásokban ezek általában mind komponensként vannak kifejezve.
Például készíthetünk egy App
komponenst, ami több Welcome
komponenst renderel:
function Welcome(props) {
return <h1>Helló, {props.name}</h1>;
}
function App() {
return (
<div>
<Welcome name="Sára" /> <Welcome name="Kata" /> <Welcome name="Edit" /> </div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
Tipikusan az új React alkalmazásoknak van egy App
komponensük a legfelsőbb szinten. Azonban ha egy meglévő alkalmazásba integrálod a Reactet, dolgozhatsz lentről felfelé fokozatosan haladva, kezdve kis komponensekkel, mint egy Button
amíg el nem éred a nézet hierarchia csúcsát.
Komponensek kivonása
Ne félj a komponenseket kisebb komponensekké feldarabolni.
Vedd ezt a Comment
komponenst példának:
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<img className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
Ez fogad egy author
(objektumot), text
(karakterláncot), és date
(dátumot) props-ként, és egy kommentet ír le egy közösségi média weblapon.
Ezt a komponenst furfangos lehet megváltoztatni a sok egymásba ágyazás miatt, és nehéz is újra felhasználni az egyedülálló részeit. Vonjunk ki egy pár komponenst belőle.
Először is kivonjuk az Avatar
komponenst:
function Avatar(props) {
return (
<img className="Avatar" src={props.user.avatarUrl} alt={props.user.name} /> );
}
Az Avatar
-nak nem kell tudnia, hogy mit is renderelünk a Comment
-ben. Ezért is adtunk a prop-jának egy általánosabb nevet mint a user
, az author
helyett.
Ajánljuk a prop-ok elnevezését a komponens saját szemszögéből nézve, a kontextus helyett amiben az használva van.
Most egy kicsit tudunk egyszerűsíteni a Comment
komponensen:
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<Avatar user={props.author} /> <div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
A következőben kivonjuk a UserInfo
komponenst ami az Avatar
-t rendereli a felhasználó neve mellett:
function UserInfo(props) {
return (
<div className="UserInfo"> <Avatar user={props.user} /> <div className="UserInfo-name"> {props.user.name} </div> </div> );
}
Ez tovább egyszerűsíti a Comment
komponensünket:
function Comment(props) {
return (
<div className="Comment">
<UserInfo user={props.author} /> <div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
A komponensek kivonása elsőre morgós munkának tűnhet, de nagyobb alkalmazások esetén gyorsan megtérül, ha egy újrafelhasználható komponenspalettával rendelkezünk. Egy jó ökölszabály, ha a felhasználói kezelőfelületed valamelyik része többször fel van használva (Button
, Panel
, Avatar
), vagy elég bonyolult saját magában is (App
, FeedStory
, Comment
), akkor jó jelölt lehet arra, hogy egy külön komponensbe emeljük ki.
A prop-ok csak olvashatók
Függetlenül hogy egy komponenst függvényként vagy osztályként deklarálsz, az soha nem módosíthatja annak saját prop-jait. Vedd ezt a sum
függvényt:
function sum(a, b) {
return a + b;
}
Egy ilyen függvényt “tiszta” függvénynek nevezünk, mert nem kísérli megváltoztatni a bemenetét, és mindig ugyanazt az eredményt adja ugyanazon bemenet esetében.
Összehasonlításképpen ez a függvény nem tiszta, mert megváltoztatja a saját bemenetét:
function withdraw(account, amount) {
account.total -= amount;
}
A React elég rugalmas, de van egy szigorú szabálya:
Minden React komponensnek tiszta függvényként kell viselkednie annak prop-jaira tekintettel
Természetesen az alkalmazások felhasználói felületei dinamikusak és idővel változnak. A következő fejezetben bemutatunk egy új koncepciót, az állapotot, vagyis a “state”-t. A állapotok lehetővé teszik a React komponenseknek hogy idővel megváltoztassák a kimenetüket a felhasználó interakciói, hálózati válaszok, vagy bármi más esetén, anélkül, hogy ezt a szabályt megszegnénk.