Zmena stavu rodiča v dcérskom komponente v React
V predchádzajúcej lekcii sme mali stav s údajmi uložený v rodičovskom komponente a dcérske komponenty tieto údaje dostávali vo forme props.
Teraz povedzme, že chceme naše produkty meniť.
Urobme napríklad tlačidlo, ktoré bude
umiestňovať náš produkt do košíka. Na začiatok
poďme do nášho poľa s produktmi pridať
pole inCart, ktoré ukazuje, či je produkt
v košíku alebo nie:
const initProds = [
{id: id(), name: 'product1', cost: 100, inCart: false},
{id: id(), name: 'product2', cost: 200, inCart: false},
{id: id(), name: 'product3', cost: 300, inCart: false},
];
V komponente Products do tagu s produktom
pridajme ešte jeden atribút inCart:
function Products() {
const [prods, setProds] = useState(initProds);
const items = prods.map(prod => {
return <Product
key ={prod.id}
name ={prod.name}
cost ={prod.cost}
inCart={prod.inCart}
/>;
});
return <div>
{items}
</div>;
}
Poďme v dcérskom komponente Product
urobiť výpis informácií o košíku a tlačidlo
na pridanie do košíka:
function Product({ id, name, cost, inCart }) {
return <div>
name: <span>{name}</span>,
cost: <span>{cost}</span>,
<span>{inCart ? 'in cart' : 'not in cart'}</span>
<button>to cart</button>
</div>;
}
Realizujme pridanie
Podľa pravidiel React komponent by nemal
meniť svoje props. To znamená, že
dcérsky komponent nemôže sám seba
vložiť do košíka zmenou props inCart.
To nie je správne.
Správne bude požiadať rodičovský komponent,
aby zmenil svoj stav prods, vložil
určitý produkt do košíka.
Pozrime sa, ako sa to robí.
V komponente-rodičovi urobme funkciu addToCart,
ktorá parametrom prijíma id produktu
a pre tento produkt mení vlastnosť inCart
na true:
function addToCart(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.inCart = true;
}
return prod;
}));
}
Do tagu s produktom pridajme atribút, do ktorého
odošleme našu vytvorenú funkciu, a tiež
atribút, do ktorého odošleme id produktu:
const items = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name ={prod.name}
cost ={prod.cost}
inCart ={prod.inCart}
addToCart={addToCart}
/>;
});
Ako vidíte, do props komponentov je možné odosielať nielen nejaké údaje, ale aj funkcie.
Výsledný kód triedy Products bude
nasledovný:
function Products() {
const [prods, setProds] = useState(initProds);
function addToCart(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.inCart = true;
}
return prod;
}));
}
const items = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name ={prod.name}
cost ={prod.cost}
inCart ={prod.inCart}
addToCart={addToCart}
/>;
});
return <div>
{items}
</div>;
}
Teraz v dcérskej triede budeme mať prístupnú
funkciu addToCart. Zavolajme túto funkciu
kliknutím na tlačidlo, odovzdajúc jej parametrom
id produktu:
function Product({ id, name, cost, inCart, addToCart }) {
return <div>
name: <span>{name}</span>,
cost: <span>{cost}</span>,
<span>{inCart ? 'in cart' : 'not in cart'}</span>
<button onClick={() => addToCart(id)}>to cart</button>
</div>;
}
Výsledkom bude, že pri kliknutí na tlačidlo v potomkovi sa zavolá funkcia rodiča, ktorá zmení rodičovský stav. Zmena rodičovského stavu spôsobí prekreslenie a prekreslí náš produkt, odovzdajúc mu zmenený props.
Vezmite komponent User z predchádzajúcej
lekcie. Urobte tak, aby sa v ňom objavilo
tlačidlo na zabanovanie používateľa.