Змяненне стэйту бацькі ў даччыным кампаненце ў React
У папярэднім уроке ў нас стэйт з данымі захоўваўся ў бацькоўскім кампаненце, а даччыныя кампаненты атрымлівалі гэтыя даныя ў выглядзе пропсаў.
Хай цяпер мы хочам змяняць нашы прадукты.
Зробім, да прыкладу, кнопку, якая будзе
змяшчаць наш прадукт у кошык. Для пачатку
дадаймо ў наш масіў з прадуктамі
поле 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>;
}
Давайце ў даччыным кампаненце 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 кампанент не павінен
змяняць свае пропсы. Гэта значыць, што
даччыны кампанент не можа пакласці сам
сябе ў кошык, змяніўшы пропс inCart.
Гэта не правільна.
Правільна будзе папрасіць бацькоўскі кампанент
змяніць свой стэйт 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}
/>;
});
Як вы бачыце, у пропсы кампанентаў можна перадаваць не толькі якіясьці даныя, але і функцыі.
Выніковы код класа 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>;
}
Цяпер у даччыным класе ў нас будзе даступная
функцыя 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>;
}
Атрымаецца, што па кліку на кнопку ў нашчадку выклічацца функцыя бацькі, якая і зменіць бацькоўскі стэйт. Змяненне бацькоўскага стэйту выкліча перарэндэрынг і перамалюе наш прадукт, перадаўшы яму зменены пропс.
Вазьміце кампанент User з папярэдняга
ўрока. Зрабіце так, каб у ім з'явілася
кнопка для бана юзера.