0

I am building this project on NextJS where I want to build a shopping cart. For that, I decided to use useContext hook. So basically what I did is pretty basic. Create a ShoppingCartContext, add a addToCart function which will push the data to store. But when I press the add to cart button it shows me that,

store.push is not a function.

edit: When I press the button first time, nothing happens. When I press it the 2nd time it gives the mentioned error. I think I did some basic stuff wrong in the code which is why I am getting this error. My context code

import {
  createContext,
  useCallback,
  useContext,
  useState,
  useEffect,
} from "react";

const ShoppingCartContext = createContext();

export function ShoppingCartContextProvider({ children }) {
  const [store, setStore] = useState([]);

  return (
    <ShoppingCartContext.Provider
      value={{
        store,
        setStore,
      }}
    >
      {children}
    </ShoppingCartContext.Provider>
  );
}

export function useShoppingCartContext() {
  const { store, setStore } = useContext(ShoppingCartContext);

  //function to push data to array
  const addToCart = (product) => {
    setStore(store.push(product));
  };

  return {
    store,
    setStore,
    addToCart,
  };
}

Where I called the button component to add data

import { useRouter } from "next/router";
import { useState } from "react";
import { useShoppingCartContext } from "../../context/CartContext";

const SingleProduct = ({ product, categories }) => {
  const { store, setStore, addToCart } = useShoppingCartContext();
  const router = useRouter();
  const breadcrumb = router.components["/shop/[[...category]]"].resolvedAs;

  const [count, setCount] = useState(0);
  const increment = () => {
    setCount(count + 1);
  };
  const decrement = () => {
    setCount(count - 1);
  };

  return (
    <>
   
        <Button
              onClick={() => {
                addToCart(product); // product is basically an object which holds all the info of the single product
              }}
            >
              Add to Cart
            </Button>
    </>
   )
} 

my _app.js file

import "../styles/globals.css";
import { ChakraProvider } from "@chakra-ui/react";
import { ShoppingCartContextProvider } from "../context/CartContext";

function MyApp({ Component, pageProps }) {
  return (
    <ChakraProvider>
      <ShoppingCartContextProvider>
        <Component {...pageProps} />
      </ShoppingCartContextProvider>
    </ChakraProvider>
  );
}

export default MyApp;

please take a look at this.

2
  • Did you try to use let instead const when declaring store? Commented Jul 31, 2022 at 9:21
  • 3
    @LuisGar const/let doesn't matter. Still gives me the same error. Commented Jul 31, 2022 at 10:24

1 Answer 1

4

For updating state which is array you need to do

setStore(store => [...store, product])

//OR 

// make clone of store and then setStore
temp=[...store]
temp.push(product)
setStore(temp)

EXPLANATION OF CURRENT BEHAVIOUR

  1. In your case it's working 1st time as you have initialized store as [] empty array.
  2. And because it's an array it has .push() method.
  3. But [].push(val) will not return an array it will return the length of array.
  4. And therefore after 1st time store get's the value of numeric datatype which does not has .push() method.

Below you can see the result of .push() your self.

arr=[1,2,3] // length 3
console.log(`initial array`)
console.log(arr)
console.log(`spread operator + new val`)
console.log([...arr,5]) // spread operator + new val
console.log(`.push()`)
console.log(arr.push(5),"length=",arr.length) // .push() this will return length of the arr

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.