• Манипуляции со state и несколько вопросов по рендерингу и архитектуре в реакт?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. Что с именами? NewsItem, setItem, result, clickFilter, styles, buy - никогда не пишите подобного даже в шутку. Замените: NewsItem на Product(или ShopItem), setItem - вообще удалите, result на products, clickFilter на handleAddToCartClick, styles на className, buy на cart.

    2. Нет никакого смысла передавать в ShopItem каждое свойство товара по отдельности. Только усложняете анализ вашего кода. Лучше:
    {products.map(product => (
      <ShopItem
        key={product.id}
        className={'item'}
        item={product}
        onAddToCartClick={this.handleAddToCartClick}
      />
    )}


    3. Base path на то и base path, что не должен содержать конкретный эндпоинт. Правильно:
    const BASE_PATH = 'https://api.punkapi.com/v2';
    
    /* ... */
    
    fetch(`${BASE_PATH}/beers`)


    Каким образом добавить полученные "товары" в корзину? Я не смог использовать значения из state.result для последующего их добавления в state.basket.
    result это просто массив из объектов. Можно получить доступ к любому товару с помощью this.state.result[индекс_объекта], но ничего с этими данными напрямую делать у меня не получается, как и с помощью setState

    Если вы не понимаете как работать с данными(массивы, объекты), то вам стоит сейчас заострить свое внимание на изучении этого вопроса:
    JavaScript: Структуры данных
    Вам вообще нет смысла копировать товар в массив cart, туда можно складывать только id товара и количество:
    class Store extends Component {
      state = {
        products: [],
        cart:[],
      };
    
      handleAddToCartClick = (id, quantity) => {
        const { cart } = this.state;
        const itemIndex = cart.findIndex(item => item.id === id);
    
        if (itemIndex !== -1) {
          const newCart = [...cart];
          newCart[itemIndex] = { id, quantity: cart[itemIndex].quantity + quantity };
          this.setState({ cart: newCart });
        } else {
          this.setState(prevState => ({
            cart: [
              ...prevState.cart,
              { id, quantity },
            ],
          }));
        }
      };

    const ShopItem = ({ className, item, onAddToCartClick }) => (
      <div>
        {/* ... */}
        <button onClick={() => onAddToCartClick(item.id, 1)}>Добавить в корзину</button>
      <div/>
    );

    Вопрос вытекает из 1го, а нормальная ли это практика добавлять в state данные, полученные из API? Если нет, то где тогда можно их хранить?

    По-хорошему, в redux store. redux стоит использовать тут хотя бы потому, что те же данные о товарах понадобятся и в корзине, и на странице checkout.

    Я хотел создать у каждого "товара" кнопку, которая будет менять стиль КОНКРЕТНО этого товара (это не несет никакой смысловой нагрузки, но мне хотелось это реализовать чтобы понять некоторые вещи).
    У моего компонента NewsItem есть пропс styles, который устанавливает стиль в компонент.

    Самый простой вариант использовать хук useState:
    import React, { useState } from 'react';
    
    const ShopItem = ({ className, item, onAddToCartClick } ) => {
      const [isActive, setIsActive] = useState(false);
      
      handleToggleActiveClick = () => {
        setIsActive(!isActive);
      };
    
      return (
        <div>
          <ul className={`${className}${isActive ? ' active' : ''}`}>
            {/* ... */} 
            <button onClick={handleToggleActiveClick}>Toggle active</button>
          </ul>
        <div/>
      );
    }
    Ответ написан
    1 комментарий