【问题标题】:Adding multiple items to shopping cart将多个商品添加到购物车
【发布时间】:2021-05-23 16:36:16
【问题描述】:

在一个小型服装网站上工作,我在连接购物车时遇到了问题。

现在,我设法添加了一个“添加到购物车”按钮,它将所需的信息发送到购物车本身。但是目前您只能发送一种产品,并且它只显示一种产品。

我在使用该网站的另一个功能时遇到了类似的问题,但只需创建一个新对象并使用扩展运算符即可解决。我也尝试对购物车执行此操作,但没有任何效果。

我不能 100% 确定如何将多个商品添加到购物车。

OBS: 另一个问题。即使我刷新页面,这些商品仍应在购物车中,LocalStorage 是实现该功能的好方法吗?

这是购物车代码:

const Cart = (props) => {
  const [isRemoved, setIsRemoved] = useState(false);

  let history = useHistory();

  const returnHome = () => history.push("/");

  const { cartItems } = useContext(AddToCartContext); 

  return (
    <StyledApp className={classes.container}>
      <div className={classes.top}>
        <div className={classes.location}>
          <span>home / shopping cart</span>
        </div>
        <div className={classes.title}>
          <h1>shopping cart</h1>
        </div>
      </div>
      <div className={classes.content}>
        <div className={classes.grid_container}>
          <Fragment>
            {cartItems === null ? (
              <p>Cart is empty</p>
            ) : (
              <Fragment>
                <Product
                  img={cartItems?.img}
                  name={cartItems?.name}
                  price={cartItems?.price}
                  color={cartItems?.color}
                  id={cartItems?.id}
                />
                <Line></Line>
              </Fragment>
            )}
          </Fragment>
        </div>
      </div>
      <div className={classes.bottom}>
        <div className={classes.options}>
          <OptionsBox>
            <LeftArrow />
            <span onClick={returnHome} className={classes.options_text}>
              continue shopping
            </span>
          </OptionsBox>
          <OptionsBox>
            <span className={classes.options_text}>clear shopping cart</span>
            <Trash />
          </OptionsBox>
        </div>
      </div>
      <footer className={classes.cart_footer}>
        <CartFooter />
      </footer>
    </StyledApp>
  );
};

这是添加项目时的代码(缩短):

import { AddToCartContext } from "../../Contexts/AddToCartContext";
const ProductContent = (props) => {
const { setCartItems } = useContext(AddToCartContext);
return (
                  <button
                    type="button"
                    onClick={() =>
                      setCartItems({
                        name: props.name,
                        price: props.price,
                        color: props.mainImg?.colour,
                        img: props.mainImg?.url,
                        id: params.productid,
                      })
                    }
                    className={classes.add_to_cart}
                  >
                    <Cart />
                    add to cart
                  </button>
);
}

编辑

根据要求:

AddToCartContext.js 代码:

import React from "react";

const AddToCartContext = React.createContext(null);

export default AddToCartContext;

App.js 代码:

function App() {
  const [cartItems, setCartItems] = useState({});

  return (
    <AddToCartContext.Provider value={{ cartItems, setCartItems }}>
      <ThemeProvider theme={themeMode}>
        {/* GlobalStyles skapas i ./themes.js */}
        <GlobalStyles />
        <Router>
          <Route exact path="/cart">
            <ShoppingCart theme={theme} toggleTheme={toggleTheme} />
          </Route>
          <Route exact path="/category/:type/:id/:productid">
            <FetchAPI />
          </Route>
          //....
        </Router>
      </ThemeProvider>
    </AddToCartContext.Provider>
  );
}

【问题讨论】:

  • setCartItems 负责将您的新项目推送到数组中还是只是覆盖当前状态?我想像 items.push(newItem) 这样的东西会在那里作为基本的东西。
  • 是的 @LuisSardon ,setCartItems 推送项目。我为此使用了 Context API。
  • 我们有机会看到AddToCartContext 代码吗?
  • 是的,当然,我会快速编辑帖子!
  • 可以肯定的是,问题是您的购物车一次只能存储一件商品,对吧?

标签: javascript reactjs


【解决方案1】:

你需要保持旧状态,试试这个:

首先你需要将你的 cartItems 默认值设置为一个空数组:

const [cartItems, setCartItems] = useState([]);

然后持久化使用setCartItems时的状态:

setCartItems(
  (cartItems) => [
    ...cartItems,
    {
      name: props.name,
      price: props.price,
      color: props.mainImg?.colour,
      img: props.mainImg?.url,
      id: params.productid,
    }
  ]
)

最后,当 carItems 不为 null 时,您只渲染一个项目,您必须将其更改为迭代 cartItems:

<Fragment>
  {cartItems.length === 0 ? (
    <p>Cart is empty</p>
  ) : cartItems.map((item) => (
    <Fragment>
      <Product
        img={item?.img}
        name={item?.name}
        price={item?.price}
        color={item?.color}
        id={item?.id}
      />
      <Line></Line>
    </Fragment>
  ))}
</Fragment>

这不能解决产品重复问题,但可以在购物车级别解决,方法是在呈现之前减少您的 cartItems。

【讨论】:

  • 我收到TypeError: cartItems is not iterable。甚至不确定这意味着什么?
  • 是的,我注意到您的默认状态是一个对象,所以您必须将默认状态更改为一个数组(可迭代),我只是在第一步中添加了它。
  • 嗯,是的,它有效,但我的谷歌崩溃了。它正在记录相同的产品数百次。
  • 好的,我刚刚发现你只渲染了一个元素,假设 cartItems 是一个对象……让我添加第三步,希望能解决问题。
  • 啊,是的,我现在遇到的问题是我的控制台收到了cartItems 的垃圾邮件。下面是截图:gyazo.com/fb6c79ff559afc5ffde1a898f3a14eca如果我没记错,这里可以用useMemo吗?
猜你喜欢
  • 2020-01-14
  • 2016-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 2018-04-10
相关资源
最近更新 更多