OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

UseContext is not a function

  • Thread starter Thread starter Davi Sá
  • Start date Start date
D

Davi Sá

Guest
I'm trying to use the context that I created to a really simple shopping cart example, for that, I created some functions and when I try to use it inside of my component, the error pops up.
I'm actually a beginner when it comes to using Context API, so if anyone could help, I'd be really happy.
Here's my context

Code:
"use client";
import { createContext, useState, ReactNode } from "react";
import { ShoppingCartProviderProps } from "../types/ShoppingCartProvider";
import { ShoppingCartFunction } from "../types/ShoppingCartFunction";
import { ProductCartItem } from '../types/Product';

export const ShoppingCartContext = createContext({} as ShoppingCartFunction);

export function ShoppingCartProvider({ children }: ShoppingCartProviderProps) {
  const [cartItem, setCartItem] = useState<ProductCartItem[]>([]);

  function getItemQuantity(id: number) {
    return cartItem.find(item => item.id === id)?.quantity || 0;
  }

  function increaseItemQuantity(id: number) {
    setCartItem(currItems => {
      if (currItems.find(item => item.id === id) == null) {
        return [...currItems, { id, quantity: 1 }];
      } else {
        return currItems.map(item => {
          if (item.id === id) {
            return { ...item, quantity: item.quantity + 1 };
          } else {
            return item;
          }
        });
      }
    });
  }

  function decreaseItemQuantity(id: number) {
    setCartItem(currItems => {
      if (currItems.find(item => item.id === id)?.quantity === 1) {
        return currItems.filter(item => item.id !== id);
      } else {
        return currItems.map(item => {
          if (item.id === id) {
            return { ...item, quantity: item.quantity - 1 };
          } else {
            return item;
          }
        });
      }
    });
  }

  function removeFromCart(id: number) {
    setCartItem(currentItems => {
      return currentItems.filter(item => item.id !== id);
    });
  }

  return (
    <ShoppingCartContext.Provider value={{ getItemQuantity, increaseItemQuantity, decreaseItemQuantity, removeFromCart }}>
      {children}
    </ShoppingCartContext.Provider>
  );
}

How I'm getting the data from API:

Code:
export const getData = async () => {

  const res = await fetch('https://fakestoreapi.com/products?limit=5');
  
  if (!res.ok) {
    throw new Error();
  }

  return res.json();
};

And the component that I'm trying to render within the context

Code:
import { ShoppingCartContext } from "@/app/context/ShoppingCartContext";
import { getData } from "@/app/data/fetchData";
import { ProductCardDescType } from "@/app/types/Product";
import ProductCard from "@/components/ProductCard/ProductCard";
import { useContext } from "react";

export default async function Store() {
  const post = await getData();

  const { getItemQuantity } = useContext(ShoppingCartContext)

  return (
    <div>
      <h1>Store</h1>
      {post.map((product: ProductCardDescType) => (
        <ProductCard key={product.id} {...product} />
      ))}
    </div>
  );
}

Provider:

Code:
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import NavBar from "@/components/NavBar/NavBar";
import { ShoppingCartProvider } from "./context/ShoppingCartContext";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <ShoppingCartProvider>
          <NavBar/>
          {children}
        </ShoppingCartProvider>
      </body>
    </html>
  );
}

I wanna use it the context within the component, and then use the other functions that I created for it.

<p>I'm trying to use the context that I created to a really simple shopping cart example, for that, I created some functions and when I try to use it inside of my component, the error pops up.<br />
I'm actually a beginner when it comes to using Context API, so if anyone could help, I'd be really happy.<br />
Here's my context</p>
<pre><code>"use client";
import { createContext, useState, ReactNode } from "react";
import { ShoppingCartProviderProps } from "../types/ShoppingCartProvider";
import { ShoppingCartFunction } from "../types/ShoppingCartFunction";
import { ProductCartItem } from '../types/Product';

export const ShoppingCartContext = createContext({} as ShoppingCartFunction);

export function ShoppingCartProvider({ children }: ShoppingCartProviderProps) {
const [cartItem, setCartItem] = useState<ProductCartItem[]>([]);

function getItemQuantity(id: number) {
return cartItem.find(item => item.id === id)?.quantity || 0;
}

function increaseItemQuantity(id: number) {
setCartItem(currItems => {
if (currItems.find(item => item.id === id) == null) {
return [...currItems, { id, quantity: 1 }];
} else {
return currItems.map(item => {
if (item.id === id) {
return { ...item, quantity: item.quantity + 1 };
} else {
return item;
}
});
}
});
}

function decreaseItemQuantity(id: number) {
setCartItem(currItems => {
if (currItems.find(item => item.id === id)?.quantity === 1) {
return currItems.filter(item => item.id !== id);
} else {
return currItems.map(item => {
if (item.id === id) {
return { ...item, quantity: item.quantity - 1 };
} else {
return item;
}
});
}
});
}

function removeFromCart(id: number) {
setCartItem(currentItems => {
return currentItems.filter(item => item.id !== id);
});
}

return (
<ShoppingCartContext.Provider value={{ getItemQuantity, increaseItemQuantity, decreaseItemQuantity, removeFromCart }}>
{children}
</ShoppingCartContext.Provider>
);
}
</code></pre>
<p>How I'm getting the data from API:</p>
<pre><code>export const getData = async () => {

const res = await fetch('https://fakestoreapi.com/products?limit=5');

if (!res.ok) {
throw new Error();
}

return res.json();
};
</code></pre>
<p>And the component that I'm trying to render within the context</p>
<pre><code>import { ShoppingCartContext } from "@/app/context/ShoppingCartContext";
import { getData } from "@/app/data/fetchData";
import { ProductCardDescType } from "@/app/types/Product";
import ProductCard from "@/components/ProductCard/ProductCard";
import { useContext } from "react";

export default async function Store() {
const post = await getData();

const { getItemQuantity } = useContext(ShoppingCartContext)

return (
<div>
<h1>Store</h1>
{post.map((product: ProductCardDescType) => (
<ProductCard key={product.id} {...product} />
))}
</div>
);
}
</code></pre>
<p>Provider:</p>
<pre><code>import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import NavBar from "@/components/NavBar/NavBar";
import { ShoppingCartProvider } from "./context/ShoppingCartContext";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>
<ShoppingCartProvider>
<NavBar/>
{children}
</ShoppingCartProvider>
</body>
</html>
);
}
</code></pre>
<p>I wanna use it the context within the component, and then use the other functions that I created for it.</p>
 
Top