Vecāka stāvokļa maiņa bērna komponentē React
Iepriekšējā nodarbībā mūsu datu stāvoklis tika glabāts vecāku komponentē, bet bērnu komponentes saņēma šos datus kā props.
Tagad pieņemsim, ka mēs vēlamies mainīt savus produktus.
Izveidosim, piemēram, pogu, kas
ievietos mūsu produktu grozā. Sākumā
pievienosim mūsu produktu masīvam
lauku inCart, kas parāda, vai produkts
atrodas grozā vai nē:
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},
];
Komponentē Products produktu tagā
pievienosim vēl vienu atribūtu 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>;
}
Bērna komponentē Product
izveidosim informācijas par grozu izvadi un pogu
pievienošanai grozam:
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>;
}
Implementējam pievienošanu
Saskaņā ar React noteikumiem komponents nedrīkst
mainīt savus props. Tas nozīmē, ka
bērna komponents nevar pats sevi
ielikt grozā, mainot propu inCart.
Tas nav pareizi.
Pareizi būs palūgt vecāku komponentam
mainīt savu stāvokli prods, ievietojot
noteiktu produktu grozā.
Apskatīsim, kā tas tiek darīts.
Vecāku komponentē izveidosim funkciju addToCart,
kas parametru pieņem id produkta
un šim produktam maina īpašību inCart
uz true:
function addToCart(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.inCart = true;
}
return prod;
}));
}
Produkta tagā pievienosim atribūtu, kurā
padodam mūsu izveidoto funkciju, kā arī
atribūtu, kurā padodam produkta 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}
/>;
});
Kā redzat, komponentu propus var padot ne tikai dažus datus, bet arī funkcijas.
Gala kods klasei Products būs
šāds:
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>;
}
Tagad bērna klasē mums būs pieejama
funkcija addToCart. Izsauksim šo funkciju
uzklikšķinot uz pogas, padodot tai parametru
id produkta:
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>;
}
Izrādīsies, ka uzklikšķinot uz pogas bērnā tiks izsaukta vecāka funkcija, kas mainīs vecāka stāvokli. Vecāka stāvokļa maiņa izraisīs pārzīmēšanu un pārzīmēs mūsu produktu, padodot tam mainītu propu.
Paņemiet komponentu User no iepriekšējās
nodarbības. Izveidojiet tā, lai tajā parādītos
poga lietotāja bloķēšanai.