Vanema komponendi olemu muutmine lapse komponendis Reactis
Eelmises õppetükis oli meil andmetega olek hoitud vanema komponendis ning lapse komponendid saidsid need andmed propidena.
Oletame nüüd, et tahame oma tooteid muuta.
Teeme näiteks nupu, mis paneb
meie toote ostukorvi. Alustuseks
lisame oma toodete massiivi
välja inCart, mis näitab, kas toode
on ostukorvis või mitte:
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},
];
Komponendis Products lisame toote tegile
veel ühe atribuudi 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>;
}
Teeme lapse komponendis Product
ostukorvi kohta teabe kuvamise ja nupu
ostukorvi lisamiseks:
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>;
}
Rakendame lisamise
React'i reeglite kohaselt komponent ei tohiks
muuta oma propse. See tähendab, et
lapse komponent ei saa ise ennast
ostukorvi panna, muutes propsi inCart.
See ei ole õige.
Õige on paluda vanema komponendil
muuta oma olekut prods, pannes
kindla toote ostukorvi.
Vaatame, kuidas seda tehakse.
Vanema komponendis teeme funktsiooni addToCart,
mis parameetrina võtab vastu id toote
ja selle toote puhul muudab omadust inCart
väärtusele true:
function addToCart(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.inCart = true;
}
return prod;
}));
}
Toote tegile lisame atribuudi, millesse
edastame meie loodud funktsiooni, samuti
atribuudi, millesse edastame toote id:
const items = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name ={prod.name}
cost ={prod.cost}
inCart ={prod.inCart}
addToCart={addToCart}
/>;
});
Nagu näete, saab komponentide propstesse edastada mitte ainult mingeid andmeid, vaid ka funktsioone.
Lõplik Products klassi kood saab
järgmine:
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>;
}
Nüüd on lapse klassis meil kättesaadav
funktsioon addToCart. Kutsume selle funktsiooni
esile nupu klõpsul, edastades sellele parameetrina
id toote:
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>;
}
Tulemuseks on, et nupu klõpsul lapse komponendis kutsutakse esile vanema funktsioon, mis muudabki vanema olekut. Vanema oleku muutmine põhjustab uuesti renderdamise ja joonistab meie toote uuesti, edastades sellele muudetud propsi.
Võtke komponent User eelmisest
õppetükist. Tehke nii, et selles ilmub
nupp kasutaja banimiseks.