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.
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
store
as []
empty array..push()
method.[].push(val)
will not return an array it will return the length of array.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