Передача стейта в дочерний компонент в React

В прошлой статье "Дочерний компонент в React" было показано как вызывать компонент из компонента. В этой статье доработаем наш код небольшого интенет магазина. Добавим в него кнопку добавления товара в корзину. А чтобы состояние товара запоминалось, введём в начальный массив логическое свойство "inCart", а сам массив будем записывать в стейт, чтобы срабатывали механизмы реактивности.

Сначала модифицируем стартовый массив:
const shopItems = [
   {id: id(), name: 'Сыр', price: 100, inCart: false},
   {id: id(), name: 'Хлеб', price: 200, inCart: false},
   {id: id(), name: 'Молоко', price: 300, inCart: false},
];
Теперь изменим компонент с выводом списка продуктов("Products"), добавив в него стейт:
function Products() {
   const [prods, setProds] = useState(shopItems);

   const result = prods.map(prod => {
      return <Product
         key={prod.id} 
         name={prod.name}
         price={prod.price}
         inCart={prod.inCart} />;
   });

   return {result};
}
И чтобы вся система с добавлением товаров в корзину работала, необходимо добавить кнопку для этого действия в карточку товара (в компонент "Product"):
function Product({ id, name, price, inCart }) {
   return <div>
      Товар: {name},
      Цена: {price},
      <div>{inCart ? 'В корзине' : ''}</div>,
      <button>Добавить в корзину</button>
   </div>;
}
Мы хотим, чтобы при нажатии на кнопку "Добавить в корзину" у товара менялось свойство "inCart" на значение "true":
function addToCart(id) {
   setProds(prods.map(prod => {
      if (prod.id == id) {
         prod.inCart = true;
      }
      return prod;
   }));
}
По правилам React сам компонент не должен изменять свои принимаемые аргументы (свойства). То есть на уровне компонента "Product" декларировать эту функцию. Поэтому придётся её переместить в родительский компонент. А в дочерний компонент будем передавать указатель на эту функцию. То есть в компоненте "Products" получится так:
const result = prods.map(prod => {
   return <Product
      key={prod.id} 
      id={prod.id} 
      name={prod.name}
      price={prod.price}
      inCart={prod.inCart} 
      addToCart={addToCart} />;
});
Остаётся только добавить событие на кнопку добавления товара в корзину компонента "Product". По клику будем вызывать функцию добавления и передавать ей id нужного товара
function Product({ id, name, price, inCart, addToCart }) {
   return <div>
      Товар: {name},
      Цена: {price},
      <div>{inCart ? 'В корзине' : ''}</div>,
      <button onClick={() => addToCart(id)}>Добавить в корзину</button>
   </div>;
}
Так в дочернем компоненте будет вызываться функция, которая декларирована в родителе. React распознает изменения и перерендерит страницу, отобразив успешное добавление товара в корзину.
MouseDC.ru - хостинг, виртуальный хостинг, покупка доменов, проверка доменов, WHOIS, курсы создания сайтов, вебинары по созданию, курсы разработки сайтов, доработка сайтов, сопровождение сайтов, разработка сайтов, техподдержка сайтов
Cмотрите другие статьи:
Была ли статья полезной?
Была ли эта статья полезна? Есть вопрос?
хостинг для сайтов
Закажите недорогой хостинг Заказать

всего от 290 руб

⇡ наверх