Обновление useContext после добавления нового значения к объекту в массиве

#javascript #reactjs #ecmascript-6 #cart

Вопрос:

У меня есть корзина покупок, которую я хочу обновить новыми значениями в зависимости от выбора пользователя из select/option. Когда пользователь выбирает количество, срабатывает мой эффект использования, и к моему объекту добавляется новое значение (для точного используемого дочернего элемента).

 function ProductData({ price, id }) {
  const [itemsInCart, setItemsInCart] = useContext(ItemsInCartContext);
  const quantity = [1, 2, 3, 4, 5, 6, 7];
  const [chosenQuantity, setChosenQuantity] = useState(1);

  const quantityHandler = (quantity) => {
    setChosenQuantity(quantity.target.value);
  };

  useEffect(() => {
    const updateProductValue = () => {
      const item = itemsInCart.find((item) => item.listing_id === id);

      item.value = chosenQuantity * price;
    };
    updateProductValue();
    // How to update itemsInCart array of objects with new item value?
  }, [chosenQuantity]);

  return (
    <>
      <Quantity>
        Quantity:
        <Select value={chosenQuantity} onChange={(e) => quantityHandler(e)}>
          {quantity.map((number) => (
            <option key={Math.random()} value={number}>
              {number}
            </option>
          ))}
        </Select>
      </Quantity>
      <Price>${price}</Price>
    </>
  );
}
 

Теперь мой отредактированный объект не хранится в локальном хранилище (useContext).
Как я могу обновить свой ItemsInCartContext в useEffect, чтобы новое значение оставалось в корзине?

Комментарии:

1. не могли бы вы уточнить, о каком объекте вы говорите?

2. «не хранится в локальном хранилище (useContext)», что это значит? Контекстный API не является локальным хранилищем

3. Это пустой массив, и потенциальный объект, который можно добавить, — это объект api со многими значениями внутри, и я установил новое значение «значение».

4. Мое состояние в созданном контексте « const [itemsInCart, setItemsInCart] = useLocalStorage(«элемент», []); ` Вот почему я упоминаю локальное хранилище

Ответ №1:

Вам нужно сохранить состояние неизменным, а также позвонить setItemsInCart , чтобы установить его, прямым способом является сопоставление идентификатора целевого элемента:

 useEffect(() => {
  setItemsInCart((prev) => {
    const newItems = prev.map((item) => {
      if (item.listing_id !== id) return item;
      return {
        ...item,
        value: chosenQuantity * price,
      };
    });

    return newItems;
  });
}, [chosenQuantity]);
 

Комментарии:

1. Большое спасибо. Сейчас это работает идеально. Не могли бы вы объяснить, почему я не должен мутировать свой массив, а заменить его новым?

2. Видишь reactjs.org/docs/…