【问题标题】:Modifying object inside array with useContext使用 useContext 修改数组内的对象
【发布时间】:2020-07-10 03:26:59
【问题描述】:

我在使用 React 的 useContext 钩子时遇到了麻烦。我正在尝试更新从上下文中获得的状态,但我不知道如何。我设法更改了我想要的对象的属性值,但每次运行此函数时我最终都会添加另一个对象。这是我的一些代码:

我的“CartItem”组件中的一个方法。

const addToQuantity = () => {
    cartValue.forEach((item) => {
      let boolean = Object.values(item).includes(props.name);
      console.log(boolean);
      if (boolean) {
        setCartValue((currentState) => [...currentState, item.quantity++])
      } else {
        return null;
      }
    });
  };

呈现“CartItem”的“Cart 组件”

  const { cart, catalogue } = useContext(ShoppingContext);
  const [catalogueValue] = catalogue;
  const [cartValue, setCartValue] = cart;

  const quantiFyCartItems = () => {
    let arr = catalogueValue.map((item) => item.name);
    let resultArr = [];
    arr.forEach((item) => {
      resultArr.push(
        cartValue.filter((element) => item === element.name).length
      );
    });
    return resultArr;
  };

  return (
    <div>
      {cartValue.map((item, idx) => (
        <div key={idx}>
          <CartItem
            name={item.name}
            price={item.price}
            quantity={item.quantity}
            id={item.id}
          />
          <button onClick={quantiFyCartItems}>test</button>
        </div>
      ))}
    </div>
  );
};

那么如何保留我的 cartValue 数组中的先前对象,并且仍然修改这样一个数组中的对象内的单个属性值?

编辑:这是 ShoppingContext 组件!

import React, { useState, createContext, useEffect } from "react";
import axios from "axios";

export const ShoppingContext = createContext();

const PRODUCTS_ENDPOINT =
  "https://shielded-wildwood-82973.herokuapp.com/products.json";

const VOUCHER_ENDPOINT =
  "https://shielded-wildwood-82973.herokuapp.com/vouchers.json";

export const ShoppingProvider = (props) => {
  const [catalogue, setCatalogue] = useState([]);
  const [cart, setCart] = useState([]);
  const [vouchers, setVouchers] = useState([]);

  useEffect(() => {
    getCatalogueFromApi();
    getVoucherFromApi();
  }, []);

  const getCatalogueFromApi = () => {
    axios
      .get(PRODUCTS_ENDPOINT)
      .then((response) => setCatalogue(response.data.products))
      .catch((error) => console.log(error));
  };

  const getVoucherFromApi = () => {
    axios
      .get(VOUCHER_ENDPOINT)
      .then((response) => setVouchers(response.data.vouchers))
      .catch((error) => console.log(error));
  };

  return (
    <ShoppingContext.Provider
      value={{
        catalogue: [catalogue, setCatalogue],
        cart: [cart, setCart],
        vouchers: [vouchers, setVouchers],
      }}
    >
      {props.children}
    </ShoppingContext.Provider>
  );
};

edit2:感谢 Diesel 关于使用 map 的建议,我想出了这段代码!

   const newCartValue = cartValue.map((item) => {
     const boolean = Object.values(item).includes(props.name);
     if (boolean && item.quantity < item.available) {
       item.quantity++;
     }
     return item;
   });
   removeFromStock();
   setCartValue(() => [...newCartValue]);
 };```

【问题讨论】:

    标签: reactjs react-hooks use-context


    【解决方案1】:

    我假设您可以在此处访问值和设置状态的能力:

    const addToQuantity = () => {
        cartValue.forEach((item) => {
          let boolean = Object.values(item).includes(props.name);
          console.log(boolean);
          if (boolean) {
            setCartValue((currentState) => [...currentState, item.quantity++])
          } else {
            return null;
          }
        });
      };
    

    现在...如果您选择[...currentState, item.quantity++],您将始终添加一个新项目。你没有改变任何东西。您还在每个项目上运行setCartValue,这不是必需的。我不确定有多少可以改变,但看起来你想改变值。这就是 map 的优势所在。

    const addToQuantity = () => {
        setCartValue((previousCartValue) => {
          const newCartValue = previousCartValue.map((item) => {
            const boolean = Object.values(item).includes(props.name);
            console.log(boolean);
            if (boolean) {
              return item.quantity++;
            } else {
              return null;
            }
          });
          return newCartValue;
        });
      };
    

    您获取所有值,进行您想要的修改,然后您可以将其设置为新状态。此外,它还创建了一个新数组,这很好,因为它不会改变您的数据。

    此外,如果您知道只有一项符合您的条件,请考虑使用 .findIndex 方法,因为它会在找到某些内容时短路(它会停在那里),然后修改该索引。

    【讨论】:

    • 地图上的好主意!!但它似乎占用了很多内存。我之前尝试过在 setState 内进行映射,但它通常会使我的应用程序崩溃。我已经实现了这段代码,它似乎现在可以工作了!! ``` const addToQuantity = () => { const newCartValue = cartValue.map((item) => { const boolean = Object.values(item).includes(props.name); console.log(boolean); if ( boolean) { item.quantity++; } return item; }) setCartValue(() => [...newCartValue]); }; ```
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-24
    • 2022-07-07
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多