简体   繁体   中英

Adding multiple items to shopping cart

Working on a little clothing website and I ran into an issue while hooking up the cart.

Now, I have managed to add a "Add To Cart" button that sends the required information to the cart itself. But at the moment you can only send one product, and it only displays one product.

I had a similar issue while working with another feature of the website, but that was solved with just creating a new object and using the spread operator. I tried doing this to the cart as well, but didn't get anything to work.

I am not 100% sure how I shall be able to add multiple items to the cart.

OBS: Another question. The items should still be in the cart even though I refresh the page, is LocalStorage a good way to make that work?

Here is the ShoppingCart code:

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>
  );
};

And here is the code for when you add the item (shorten):

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>
);
}

Edit

As requested:

AddToCartContext.js code:

import React from "react";

const AddToCartContext = React.createContext(null);

export default AddToCartContext;

App.js Code:

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>
  );
}

You need to persist the old state, try with this:

First you need to set your cartItems default value as an empty array:

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

Then persist the state when using setCartItems :

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

Lastly you are rendering just one item when carItems isn't null, you'll have to change that to iterate cartItems instead:

<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>

This won't solve for product duplication, but that can be solved at the Cart level, by reducing your cartItems before rendering.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM