Ndryshimi i state-it të prindit në komponentin fëmijë në React
Në mësimin e mëparshëm, state-i me të dhënat ruhej në komponentin prind, ndërsa komponentët fëmijë i merrnin këto të dhëna në formë të props.
Le të supozojmë tani që ne duam të ndryshojmë produktet tona.
Le të bëjmë, për shembull, një buton që do të
vendosë produktin tonë në shportë. Për fillim,
le të shtojmë në array-in tonë me produkte
fushen inCart, e cila tregon nëse produkti
është në shportë apo jo:
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},
];
Në komponentin Products në tag-un me produktin
le të shtojmë një atribut tjetër 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>;
}
Le të bëjmë në komponentin fëmijë Product
shfaqjen e informacionit për shportën dhe një buton
për shtim në shportë:
function Product({ id, name, cost, inCart }) {
return <div>
name: <span>{name}</span>,
cost: <span>{cost}</span>,
<span>{inCart ? 'në shportë' : 'jo në shportë'}</span>
<button>në shportë</button>
</div>;
}
Le të implementojmë shtimin
Sipas rregullave të React një komponent nuk duhet
të ndryshojë props-et e veta. Kjo do të thotë se
komponenti fëmijë nuk mund ta vendosë vetë
veten në shportë, duke ndryshuar prop-in inCart.
Kjo nuk është e drejtë.
Mënyra e duhur do të ishte të kërkohet nga komponenti prind
të ndryshojë state-in e vet prods, duke vendosur
në shportë një produkt të caktuar.
Le të shohim se si bëhet kjo.
Në komponentin prind le të bëjmë një funksion addToCart,
i cili si parametër pranon id e produktit
dhe për atë produkt ndryshon vetinë inCart
në true:
function addToCart(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.inCart = true;
}
return prod;
}));
}
Në tag-un me produkt le të shtojmë një atribut, në të cilin
do të kalojmë funksionin që krijuam, si dhe
një atribut, në të cilin do të kalojmë id e produktit:
const items = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name ={prod.name}
cost ={prod.cost}
inCart ={prod.inCart}
addToCart={addToCart}
/>;
});
Siç e shihni, në props-et e komponentëve mund të kalohen jo vetëm të dhëna, por edhe funksione.
Kodi përfundimtar i klasës Products do të dalë
sipas mëposhtjes:
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>;
}
Tani në klasën fëmijë do të jetë i disponueshëm
funksioni addToCart. Le ta thirrim këtë funksion
në klikim të butonit, duke i kaluar asaj si parametër
id e produktit:
function Product({ id, name, cost, inCart, addToCart }) {
return <div>
name: <span>{name}</span>,
cost: <span>{cost}</span>,
<span>{inCart ? 'në shportë' : 'jo në shportë'}</span>
<button onClick={() => addToCart(id)}>në shportë</button>
</div>;
}
Do të dalë që në klikim të butonit në fëmijë do të thirret funksioni i prindit, i cili do të ndryshojë state-in e prindit. Ndryshimi i state-it të prindit do të shkaktojë ri-renderim dhe do të rivizatojë produktin tonë, duke i kaluar atij prop-in e ndryshuar.
Merrni komponentin User nga mësimi i mëparshëm.
Bëni që në të të shfaqet një buton për bllokim (ban) të userit.