Home > Back-end >  React Context Api using function from context provider
React Context Api using function from context provider

Time:10-04

i'm trying to use contextApi to handle a shop cart list of items.

I alredy have a context for auth in project and it's working fine, but this new context for cart is giving me problems.

I have a function named addItem(item: ShoppingItem) when i try to use this function on my components i get a error that addItem is not a function. I'll show my code bellow. Thks

Cart Context:

import { createContext, useState } from 'react';

export interface ShoppingCartContextType {
    list: number;
    addItem(item: ShoppingItem): Promise<void>;
    logout(): void;
}; 

export interface ShoppingItem {
    id: string
}

const ShoppingCartContext = createContext<ShoppingCartContextType>({} as ShoppingCartContextType);

export const ShoppingCartProvider: React.FC = ({children}) => {
    const [shoppingCart, setShoppingCart] = useState<ShoppingItem[]>([{id: "item de merda"}]);

    async function addItem(item: ShoppingItem): Promise<void>{
        console.log('adding an item')
        setShoppingCart(current => [...current, item])
       
        return new Promise((resolve) => {
           resolve();
        });
    }

    function logout() {
      localStorage.clear();
    }

  return (
    <ShoppingCartContext.Provider 
        value= {{ list: shoppingCart.length,  addItem, logout}}>
        {children}
    </ShoppingCartContext.Provider>
  );
};

export default ShoppingCartContext;

Component who uses the context:

import { useContext } from 'react';

import './styles.css';
import { toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';  

import { FaShoppingCart } from 'react-icons/fa';
import AuthContext from '../../contexts/auth';
import ShoppingCartContext, { ShoppingItem } from '../../contexts/shoppingCart';
import { NonAuthRoutes } from '../../helpers/Authentication/authenticationRoutes';
import { useHistory } from 'react-router-dom';

interface Props {
    productId: string | undefined;
    productName: string | undefined;
    price: number | undefined;
    quantity: number | undefined;
}

function BuyButton({productId, productName, price, quantity}: Props) {

    
    const history = useHistory();
    const {signed} = useContext(AuthContext);
    const {addItem} = useContext(ShoppingCartContext);

    async function handleBuy(e: React.FormEvent<HTMLButtonElement>) {
        e.stopPropagation();
        addItem({id: productId} as ShoppingItem);
        if (!signed) {
            toast.warn("Você esta sendo redirecionado para a página de login", {autoClose:15000});
            setTimeout(() => {
                history.push(NonAuthRoutes.login);
            }, 800);
            return ;
        }
    }

    return (
        <div className="button-container">
            <button className="button" onClick={handleBuy}>
                <FaShoppingCart />
                COMPRAR
            </button>
        </div>
    );
}

export default BuyButton;

CodePudding user response:

This error normally occurs because BuyButton is not child of the ShoppingCartProvider and you have not given a default value for the addItem method when initialising the context.

You can back this up by giving the ShoppingCartContext a default value for addItem like so:

const ShoppingCartContext = createContext<ShoppingCartContextType>({
    addItem: () => alert('test')
});

See this CodeSandbox as an example:

https://codesandbox.io/s/nifty-williams-ziysn?file=/src/App.tsx

  • Related