Komponenty w React byłyby znacznie mniej funkcjonalne, gdybyśmy nie mogli przekazywać do nich zmiennych. Props działają podobnie do atrybutów tagów HTML i umożliwiają komponentom otrzymywanie danych z zewnątrz.
React automatycznie przekazuje props jako specjalny argument do każdego komponentu funkcyjnego.
function ButtonSubmit(props) {
return <button class="{props.className}">{props.title}</button>;
}
W powyższym przykładzie, komponent ButtonSubmit otrzymuje obiekt props(nazwa jest dowolna), który zawiera atrybuty określone w kodzie JSX.
Przykład:
import { SubmitButton } from './SubmitButton';
function Form() {
return (
<form>
{/* inne elementy */}
<SubmitButton className="btn" title="Wyślij" />
</form>
);
}
Warto zaznaczyć że do props-ów możemy dodać każdą wartość w JavaScript, tablicę, obiekty czy funkcje.
Zawartość komponentu – children
Komponenty mogą zawierać dzieci, podobnie jak tagi HTML.
import { SubmitButton } from './SubmitButton';
function Form() {
return (
<form>
{/* inne elementy */}
<SubmitButton className="btn">Wyślij</SubmitButton>
</form>
);
}
aby odczytać tą zawartość, React do przekazywanego obiektu w argument komponentu, dodaje specjalny atrybut children
który zawiera właśnie zawartość komponentu
Przykład:
function ButtonSubmit(props) {
return <button class="{props.className}">{props.children}</button>;
}
Destrukturyzacja props
Możemy ułatwić sobie odczyt props-ów poprzez destrukturyzacje dostępną w JavaScript
function ButtonSubmit({className, title, children}) {
return <button class="{className}">{title}</button>;
}
Możemy również ustawić wartości domyślne:
function ButtonSubmit({className, title, alt="Submit button", children}) {
return <button class="{className}">{title}</button>;
}
Operator Spread (…) dla props
Przy renderowaniu komponentu w pętli, zamiast wyliczać wszystkie props, możemy użyć składni Spread:
import { PersonCart } from './PersonCart';
function Form() {
const PERSON = [{name: "Marek", age: 23, lastName:"Kowalski", id:1}, {name: "Tomek", age: 35, lastName:"Nowak", id:1}];
return (
<form>
{PERSON.map(person => (
{/* Zamiast takiego przekazania */}
<PersonCart key={person.id} name="{person.name}" age="{person.age}" lastName="{person.lastName}" />
{/* Możemy krócej */}
<PersonCart key={person.id} {...person} />
))}
</form>
);
}
W tym przykładzie, operator Spread (…) pozwala na łatwe przekazanie wszystkich właściwości obiektu person jako props do komponentu PersonCart.
Inne wykorzystanie operatora Spread
function Section({ title, children, ...props }) {
return (
<section {...props}>
<h3>{title}</h3>
{children}
</section>
);
}
function onClick() {
// Definicja funkcji obsługi kliknięcia
}
function App() {
return (
<>
<Section title="To do list" id="todos" className="redTitle" onClick={onClick}>
<div>
{/* zawartość sekcji ... */}
</div>
</Section>
</>
);
}
Zamiast przypisywać każdy atrybut indywidualnie, operator spread umożliwia przekazanie całego zbioru właściwości (props) naraz. Dzięki temu, wszystkie właściwości przekazane do komponentu Section, takie jak id, className, czy onClick, są automatycznie stosowane do wewnętrznego tagu section, co znacznie upraszcza strukturę kodu i czyni go bardziej czytelnym. To podejście jest szczególnie przydatne, gdy mamy do czynienia z komponentami o dużej liczbie atrybutów, ponieważ eliminuje potrzebę manualnego przypisywania każdej właściwości osobno.