Szülő állapotának megváltoztatása gyermek komponensben Reactban
Az előző leckében az adatokat tartalmazó állapot a szülő komponensben volt tárolva, a gyermek komponensek pedig ezeket az adatokat props formájában kapták meg.
Tegyük fel most, hogy módosítani szeretnénk termékeinket.
Készítsünk például egy gombot, amely a
kosárba helyezi a termékünket. Kezdetben
adjuk hozzá a termékeket tartalmazó tömbhöz
a inCart mezőt, amely megmutatja, hogy a termék
a kosárban van-e vagy sem:
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},
];
A Products komponensben a terméket tartalmazó elemhez
adjunk hozzá még egy inCart attribútumot:
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>;
}
Készítsük el a gyermek Product komponensben
a kosárral kapcsolatos információk megjelenítését és egy gombot
a kosárba helyezéshez:
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>;
}
Valósítsuk meg a hozzáadást
A React szabályai szerint egy komponens nem változtathatja meg
a saját props-jait. Ez azt jelenti, hogy
a gyermek komponens nem tudja magát a kosárba helyezni
a inCart prop módosításával.
Ez nem helyes.
Helyesabb lesz, ha megkérjük a szülő komponenst,
hogy változtassa meg a saját prods állapotát,
egy adott terméket a kosárba téve.
Nézzük meg, hogyan is történik ez.
A szülő komponensben készítsünk egy addToCart függvényt,
amely paraméterként fogadja a termék id-ját
és ennek a terméknek módosítja a inCart tulajdonságát
true-ra:
function addToCart(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.inCart = true;
}
return prod;
}));
}
A terméket tartalmazó elemhez adjunk hozzá egy attribútumot, amelybe
átadjuk a általunk létrehozott függvényt, valamint
egy attribútumot, amelybe átadjuk a termék id-ját:
const items = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name ={prod.name}
cost ={prod.cost}
inCart ={prod.inCart}
addToCart={addToCart}
/>;
});
Amint látjátok, a komponensek props-jaiba nem csak adatokat, hanem függvényeket is lehet átadni.
A Products osztály végső kódja a
következő lesz:
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>;
}
Most a gyermek osztályban elérhető lesz
a addToCart függvény. Hívjuk meg ezt a függvényt
a gombra kattintáskor, átadva neki paraméterként
a termék id-ját:
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>;
}
Az eredmény az lesz, hogy a gyermekben lévő gombra kattintáskor meghívódik a szülő függvénye, amely megváltoztatja a szülő állapotát. A szülő állapotának megváltoztatása újrarajzolást indít el és újrarajzolja a termékünket, átadva neki a módosított propot.
Vegyétek az előző leckéből a User komponenst.
Úgy alakítsátok át, hogy benne megjelenjen egy gomb a felhasználó kitiltásához.