Propy w React dla początkujących: przekształcanie statycznych komponentów w szablony
Dowiedz się, w jaki sposób właściwości React przekazują dane z komponentów rodzicielskich do potomnych, jak funkcjonuje obiekt właściwości, jakie typy wartości można przekazać oraz dlaczego jednokierunkowy przepływ danych jest przydatny.
Źródła: Part 5A — React Props Explained: Pass Data Between Components Like a Pro
Rozbicie interfejsu React na komponenty to zaledwie połowa procesu ponownego wykorzystania. Komponent, który zawsze renderuje ten sam tekst, jest jedynie elementem do skopiowania i wklejenia, a nie elementem budulcowym. Propy to mechanizm umożliwiający komponentowi renderowanie różnego kontentu za każdym razem, gdy jest używany. Ten przewodnik wyjaśnia, czym są propy, jak dane przechodzą od komponentu nadrzędnego do potomnego, jak odczytywać propy wewnątrz komponentu oraz jakie rodzaje wartości można przekazać, aby móc przekształcić komponenty z kodem hard‑codedowanym w szablony nadające się do ponownego użycia.
Gdy komponent może pokazywać tylko jedną rzecz
Gdy już wiesz, jak budować komponenty, typowe drzewo aplikacji wygląda mniej więcej tak, z korzeniem App, który renderuje kilka sekcji:
App
│
├── Navbar
├── Hero
├── Features
├── Footer
A teraz wyobraź sobie kartę produktu w sklepie internetowym. Wyświetla ona nazwę, cenę, ocenę oraz przycisk zakupu:
-------------------------
📱 iPhone 16
₹79,999
⭐⭐⭐⭐⭐
Buy Now
-------------------------
Następnie pojawia się wymóg: pokazanie 500 produktów. Taka struktura jak opisana może wyświetlić tylko jeden telefon po tej samej cenie, więc laptopy, słuchawki i zegarki wymagałyby niemal identycznych elementów, co unieważnia sens ich istnienia. Trzeba utrzymać stałą strukturę, dostarczając przy tym za każdym razem różne dane. Właśnie do tego służą propsy.
Czym są propsy
"Props" to skrót od properties. Są to wartości, które komponent rodzicielski przekazuje komponentowi potomnemu podczas jego renderowania. Komponent określa strukturę i styl, natomiast propsy dostarczają szczegółów, które czynią każdą instancję unikalną.
Pomaga tu analogia kuchenna. Pizzeria nie wymyśla nowego przepisu na każde zamówienie – ma jeden przepis i otrzymuje różne instrukcje do dodania na każde zamówienie: dodatkowego sera, grzybów, oliwek, kukurydzy. Przepis to komponent, a dodatki to propsy.
Innymi słowy, komponent pełni rolę szablonu, a props wypełniają puste miejsca. Zamiast tworzyć osobną kartę, która zawsze pokazuje to samo, jak w tym przypadku:
Product Card
iPhone
tworzy się jedną uniwersalną kartę produktu i przekazuje do niej różne dane tam, gdzie jest używana.
Komponenty rodzicielskie, potomne i jednokierunkowy przepływ danych
Props mają sens tylko w kontekście relacji między komponentami. Każde aplikacje React to drzewo, w którym niektóre komponenty renderują inne:
App
│
├── Navbar
├── Hero
├── ProductCard
└── Footer
Tutaj App jest komponentem rodzicielskim, a Navbar, Hero, ProductCard i Footer są jego komponentami potomnymi. Komponent rodzicielski decyduje, które komponenty potomne mają zostać renderowane, a także może przekazać im informacje. Te informacje to właśnie jego props.
React wymusza jednokierunkowy przepływ danych: props przemieszczają się w dół, od komponentu rodzicielskiego do potomnego.
App
│
│ title
│ price
│ rating
▼
ProductCard
Dziecko otrzymuje title, price i rating, ale nie może przesyłać nowych wartości z powrotem przez swoje props. Z punktu widzenia dziecka props są również tylko do odczytu. Komponent nigdy nie powinien modyfikować otrzymywanych props; jeśli coś musi się z czasem zmienić, powinno to znajdować się w stanie, który zazwyczaj jest kontrolowany przez rodzica. Gdy dziecko musi przekazać informację w górę, na przykład o kliknięciu, rodzic przekazuje mu funkcję jako prop, a dziecko ją wywołuje. Ponieważ dane przepływają tylko w jednym kierunku, zawsze można prześledzić, skąd pochodzi dana wartość, idąc w górę drzewa, co znacznie ułatwia znajdowanie błędów.
Pierwszy komponent z props
Zacznij od komponentu, który wita kogoś po imieniu. Przyjmuje on parametr o nazwie props i odczytuje props.name w swoim JSX:
function Welcome(props) {
return (
<h1>Hello, {props.name}</h1>
);
}
export default Welcome;
Komponent nadrzędny go renderuje i dostarcza nazwę jako atrybut:
import Welcome from "./Welcome";
function App() {
return (
<>
<Welcome name="Ayush" />
</>
);
}
export default App;
Wynik renderowania jest następujący:
Hello, Ayush
Co robi każda część składni
Przekazywanie propów przypomina zapisywanie atrybutu HTML w tagu komponentu:
<Welcome name="Ayush" />
Pomaga to postrzegać to jako wywołanie funkcji z argumentami. Po stronie odbierającej komponent jest funkcją, której pierwszym parametrem są propy:
function Welcome(props)
React zbiera wszystkie atrybuty, które zapisaliśmy w tagu, do jednego prostego obiektu i przekazuje go jako ten parametr. Odczytywanie wartości to zwykły dostęp do właściwości:
props.name
Ponieważ komponent nadrzędny przekazał ten atrybut:
name="Ayush"
komponent renderuje:
Hello, Ayush
Nazwa props to jedynie konwencja. Wiele baz kodu rozkłada ją na listę parametrów, jak w function Welcome({ name }).
Przekazywanie kilku propów jednocześnie
Prawdziwe komponenty zazwyczaj wymagają więcej niż jednej wartości. Można dodać tyle atrybutów, ile się chce. Należy pamiętać, że łańcuchy tekstowe można zapisać w cudzysłowach, natomiast liczby i inne wartości JavaScript muszą znajdować się w nawiasach klamrowych. W poniższym fragmencie brakuje przestrzeni między nazwą komponentu a pierwszym atrybutem; powinno to wyglądać jak <Welcome name=...:
<Welcomename="Ayush"
company="OpenAI"
experience={6}
/>
Komponent odczytuje każdy prop podając jego nazwę:
function Welcome(props) {
return (
<>
<h2>{props.name}</h2>
<p>{props.company}</p>
<p>{props.experience} Years</p>
</>
);
}
I renderuje:
Ayush
OpenAI
6 Years
Zmieniając propy, ten sam komponent wyświetla zupełnie inne informacje.
Użytkowalna karta produktu
Z powrotem do sklepu. Karta teraz odczytuje swój tytuł, cenę i ocenę z atrybutów zamiast mieć je hardkodowane:
function ProductCard(props) {
return (
<div>
<h2>{props.title}</h2>
<p>₹ {props.price}</p>
<p>{props.rating}</p>
</div>
);
}
export default ProductCard;
Komponent nadrzędny może wyświetlić tyle kart, ile potrzebuje, przy czym każda ma własne dane. Cena jest przekazywana jako liczba w nawiasach kwadratowych, natomiast tytuł i ocena to łańcuchy tekstowe:
<ProductCard
title="iPhone 16"
price={79999}
rating="⭐⭐⭐⭐⭐"
/>
<ProductCard
title="Samsung S25"
price={68999}
rating="⭐⭐⭐⭐"
/>
<ProductCard
title="MacBook Air"
price={99999}
rating="⭐⭐⭐⭐⭐"
/>
Jeden komponent, trzy różne produkty – bez duplikowanych elementów markup. Dla 500 produktów również nie pisałby się ręcznie 500 tagów: dane pochodziłyby z tablicy, a karty wyświetlano by za pomocą products.map(...), przekazując pola każdego elementu jako atrybuty i nadając każdej karcie unikalny key.
Dlaczego atrybuty umożliwiają ponowne użycie
Bез atrybutów sklep potrzebuje oddzielnego komponentu dla każdego produktu:
ProductCard1
ProductCard2
ProductCard3
ProductCard4
ProductCard5
To oznacza wiele plików z niemal identycznym kodem, w których każda zmiana projektu musi być powtarzana we wszystkich miejscach. Dzięki propsom proces wygląda tak, że jeden komponent otrzymuje różne dane:
ProductCard
↓
Different Product Data
↓
Multiple Cards
Jeden plik definiuje kartę; jej instancje różnią się tylko danymi. To podstawowy wzorzec stosowany w dużych aplikacjach React i systemach projektowych.
Pomyśl o standardowym formularzu aplikacyjnym: wszyscy wypełniają te same pola, takie jak imię, wiek i adres, ale z różnymi danymi. Pusty formularz to komponent; dane wprowadzone przez użytkownika to propsy.
Jakie wartości można przekazać
Propsy nie są ograniczone do tekstu. Można przekazać dowolną wartość JavaScriptu. W przypadku ciągów znaków można używać cudzysłowów:
name="Ayush"
Liczby umieszcza się w nawiasach klamrowych, dzięki czemu React otrzymuje rzeczywistą liczbę, a nie ciąg znaków „26”:
age={26}
Logiki również używają nawiasów klamrowych:
isAdmin={true}
Należy przekazać wartość zmiennej:
name={username}
Lub wynik dowolnego wyrażenia, które jest ewaluowane przed tym, jak zostanie ono otrzymane przez dziecko:
price={500 + 200}
Tablice, obiekty i funkcje można przekazywać w ten sam sposób, wewnątrz nawiasów. Funkcje jako props służą do informowania rodziców o zdarzeniach, a specjalny prop o nazwie children umożliwia komponentowi otoczenie dowolnego kodu umieszczonego pomiędzy jego tagami otwierającymi i zamykającymi.
Wartości hard-kodowane versus props
Porównaj nagłówek hard-kodowany:
<h2>iPhone 16</h2>
z tym, który jest sterowany przez prop:
<h2>{props.title}</h2>
Pierwszy może pokazywać tylko jeden produkt; drugi może wyświetlać dowolną ich liczbę. Za każdym razem, gdy zauważysz, że wpisujesz konkretne treści do komponentu przeznaczonego do ponownego użycia, zastanów się, czy te treści nie powinny być zamiast tego propami. Unikaj jednak przeciwnego skrajności: przekształcanie każdego drobnego szczegółu w prop utrudnia korzystanie z komponentów, więc ujawniaj tylko to, co rzeczywiście się różni pomiędzy poszczególnymi użyciami.
Aby przypomnieć sobie, jak są zbudowane same komponenty, zapoznaj się z React components 101.
Główne wnioski
- Propy, skrót od properties, to wartości, które rodzic przekazuje dziecku podczas jego renderowania.
- Dane przepływają w jednym kierunku, od rodzica do dziecka, a komponenty dziecięce traktują propy jako tylko do odczytu.
props, który jest przekazywany jako pierwszy argument funkcji.children.