1

I am trying to create E-comm website with header contain cart ,login button, add wishlist button and also in body having filter out the cloths, electronics and footware section and also creeated card with product name and description price and all and also create some other pages like about us, home, contact, and add to cart page

while on product click on add to cart button im having difficulty using the useReducer() Created add To cart page and everything

CartReducer.js

export const CartReducer = (state, action) => {
  switch (action.type) {
    case "ADD_TO_CART":
      return { ...state, cart: [...state, { ...action.payload, qty: 1 }] };
    case "REMOVE_FROM CART":
      return {
        ...state,
        cart: state.cart.filter((c) => c.id !== action.payload.id),
      };

    default:
      return state;
  }
};

Context.js

import React, { createContext, useContext, useReducer } from "react";
import products from "../components/data";
import { CartReducer } from "./Reducer";
const Cart = createContext();

function Context({ children }) {
  const [state, dispatch] = useReducer(CartReducer, {
    products: products,
    cart: [],
  });

  return <Cart.Provider value={{ state, dispatch }}>{children}</Cart.Provider>;
}

export default Context;

export const CartState = () => {
  return useContext(Cart);
};

Carts.js

import React from "react";
import "../../index.css";
import { CartState } from "../../context/Context";
function Cards(props) {
  const {
    state: { products, cart },
    dispatch,
  } = CartState();
  return (
    <>
      <section id="header" className="">
        <div className="container-fluid">
          <div className="row ">
            <div className="col-12">
              <div className="row row-cols-1 row-cols-md-3 g-3">
                {products
                  .filter((itema) => itema.type === props.type)
                  .map((item, index) => {
                    return (
                      <>
                        <div className="col">
                          <div className="card" key={index}>
                            <img
                              src={item.images}
                              style={{ height: "300px" }}
                              className="card-img-top"
                              alt="..."
                            />
                            <div className="card-body">
                              <h5 className="card-title">{item.title}</h5>
                              <h5 className="card-title">
                                Price: ₹ {item.price}
                              </h5>
                              <span className="row row-cols-1 row-cols-md-1 g-1">
                                <span className="col-12">
                                  {cart.some((p) => p.id === item.id) ? (
                                    <button
                                      className="btn btn-danger"
                                      onClick={() => {
                                        dispatch({
                                          type: "REMOVE_FROM_CART",
                                          payload: item,
                                        });
                                      }}
                                      type="submit"
                                    >
                                      Remove From Cart
                                    </button>
                                  ) : (
                                    <button
                                      className="btn btn-warning"
                                      onClick={() => {
                                        dispatch({
                                          type: "ADD_TO_CART",
                                          payload: item,
                                        });
                                      }}
                                      type="submit"
                                    >
                                      Add To Cart
                                    </button>
                                  )}
                                </span>
                              </span>
                            </div>
                          </div>
                        </div>
                      </>
                    );
                  })}
              </div>
            </div>
          </div>
        </div>
      </section>
    </>
  );
}

export default Cards;

While clicking on Add to cart button found challenging to get this error

Error while clicking on ADD to CART

its really appriciate if some one help me to find the solution for this!!!

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Gajanan Shinde
  • 183
  • 1
  • 4
  • 15
  • 1
    This looks like a typo. In `ADD_TO_CART`, you have `return { ...state, cart: [...state, { ...action.payload, qty: 1 }] };`, which spreads `state` as an object (the first `...state`) and also spread `state` as an iterable (the second `...state`, inside `[]`). But `state` isn't iterable, it's a plain object. The second `...state` should be spreading the *`state.cart`* array: `return { ...state, cart: [...state.cart, { ...action.payload, qty: 1 }] };` – T.J. Crowder Nov 17 '21 at 08:20

1 Answers1

1

Initial state is an object, it's not iterable:

{
  products: products,
  cart: [],
}

The ADD_TO_CART case needs to handle this by shallow copying state.cart array into the cart property:

case "ADD_TO_CART":
  return {
    ...state,
    cart: [
      ...state.cart, // <-- shallow copy the cart state
      { ...action.payload, qty: 1 }
    ],
  };
Drew Reese
  • 165,259
  • 14
  • 153
  • 181