Verandering van Ouertoestand in Kindkomponent in React
In die vorige les het ons staat met data gestoor in die ouerkomponent, en die kindkomponente het hierdie data as props ontvang.
Laat ons nou aanneem dat ons ons produkte wil verander.
Kom ons maak byvoorbeeld 'n knoppie wat ons
produk in die mandjie sal plaas. Om mee te begin,
laat ons in ons produkarray 'n veld inCart byvoeg,
wat wys of die produk in die mandjie is of 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},
];
In die komponent Products, voeg ons nog 'n
attribute inCart by in die produk-tag:
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>;
}
Laat ons in die kindkomponent Product
die inligting oor die mandjie en 'n knoppie
om by te voeg, maak:
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>;
}
Implementeer die byvoeging
Volgens die reëls van React moet 'n komponent nie
sy eie props verander nie. Dit beteken dat die
kindkomponent nie homself in die mandjie kan plaas nie,
deur die prop inCart te verander.
Dit is nie korrek nie.
Die korrekte manier is om die ouerkomponent te vra om
sy eie state prods te verander, deur 'n
spesifieke produk in die mandjie te plaas.
Kom ons kyk hoe dit gedoen word.
In die ouerkomponent, maak ons 'n funksie addToCart,
wat 'n id van 'n produk as parameter aanvaar
en vir daardie produk die eienskap inCart verander
na true:
function addToCart(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.inCart = true;
}
return prod;
}));
}
In die produk-tag voeg ons 'n attribuut by, waarin
ons ons geskepte funksie stuur, asook
'n attribuut, waarin ons die id van die produk stuur:
const items = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name ={prod.name}
cost ={prod.cost}
inCart ={prod.inCart}
addToCart={addToCart}
/>;
});
Soos jy kan sien, kan jy in die props van komponente nie net data stuur nie, maar ook funksies.
Die finale kode van die komponent Products sal
soos volg wees:
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>;
}
Nou sal die funksie addToCart beskikbaar wees
in die kindkomponent. Laat ons hierdie funksie aanroep
op 'n klik op die knoppie, deur die id van die produk
as parameter daaraan te gee:
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>;
}
Dit sal beteken dat op 'n klik op die knoppie in die nakomeling die funksie van die ouer aangeroep sal word, wat dan die ouer se state sal verander. Die verandering van die ouer se state sal 'n herlevering veroorsaak en ons produk herteken, met die veranderde prop wat aan hom gestuur word.
Neem die komponent User uit die vorige
les. Maak so dat 'n knoppie verskyn om die gebruiker
te verban.