Ծնողի սթեյթի փոփոխում child կոմպոնենտում React-ում
Նախորդ դասում մեր տվյալներով սթեյթը պահվում էր ծնող կոմպոնենտում, իսկ child կոմպոնենտները ստանում էին այդ տվյալները props-ի տեսքով։
Ենթադրենք, հիմա մենք ուզում ենք փոխել մեր ապրանքները։
Օրինակ, ստեղծենք մի կոճակ, որը կտեղադրի
մեր ապրանքը զամբյուղում։ Սկզբից եկեք մեր ապրանքների
զանգվածին ավելացնենք inCart դաշտը, որը ցույց կտա,
արդյոք ապրանքը գտնվում է զամբյուղում, թե ոչ։
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},
];
Products կոմպոնենտում ապրանք պարունակող թեգին
ավելացնենք ևս մեկ ատրիբուտ 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>;
}
Եկեք child Product կոմպոնենտում
ստեղծենք զամբյուղի մասին տեղեկատվության արտածում և կոճակ
զամբյուղում ավելացնելու համար։
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>;
}
Իրականացնենք ավելացումը
React-ի կանոններով կոմպոնենտը չպետք է
փոխի իր props-ը։ Սա նշանակում է, որ
child կոմպոնենտը չի կարող ինքն իրեն
դնել զամբյուղ՝ փոխելով inCart prop-ը։
Սա ճիշտ չէ։
Ճիշտ կլինի խնդրել ծնող կոմպոնենտին
փոխել իր սեփական prods սթեյթը՝
տեղադրելով որոշակի ապրանք զամբյուղում։
Եկեք տեսնենք, թե ինչպես է դա արվում։
Ծնող կոմպոնենտում ստեղծենք addToCart ֆունկցիան,
որը պարամետրով ընդունում է ապրանքի id-ն
և այդ ապրանքի համար փոխում է inCart հատկությունը
true-ի։
function addToCart(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.inCart = true;
}
return prod;
}));
}
Ապրանք պարունակող թեգին ավելացնենք ատրիբուտ, որի մեջ
կփոխանցենք մեր ստեղծած ֆունկցիան, ինչպես նաև
ատրիբուտ, որի մեջ կփոխանցենք ապրանքի 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}
/>;
});
Ինչպես տեսնում եք, կոմպոնենտների props-ին կարելի է փոխանցել ոչ միայն որոշ տվյալներ, այլև ֆունկցիաներ։
Products կոմպոնենտի վերջնական կոդը կստացվի
հետևյալը։
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>;
}
Այժմ child կոմպոնենտում մեզ հասանելի կլինի
addToCart ֆունկցիան։ Եկեք կանչենք այս ֆունկցիան
կոճակի կտտոցին՝ փոխանցելով նրան պարամետրով
ապրանքի id-ն։
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>;
}
Ստացվում է, որ child-ում կոճակի վրա կտտացնելիս կկանչվի ծնողի ֆունկցիան, որն էլ կփոխի ծնողի սթեյթը։ Ծնողի սթեյթի փոփոխությունը կառաջացնի rerender և կվերագծի մեր ապրանքը՝ փոխանցելով նրան փոփոխված prop։
Վերցրեք User կոմպոնենտը նախորդ
դասից։ Արվեցնեք, որ նրանում հայտնվի
օգտագործողի արգելափակման (ban) կոճակ։