1

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;
1
  • 1
    In javascript, arrow functions and "regular" functions declarations have different scopes (blog.kevinchisholm.com/javascript/context-object-literals), I would first try changing all the functions to arrow functions (for example: change async function handleBuy(...) to const handleBuy = async () => {}) and see if that resolves the issue Commented Oct 3, 2021 at 18:28

1 Answer 1

1

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

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

1 Comment

That's exact what was happen, thks, i could add a default value like you said, or wrap everything inside de ShoppigCartProvider

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.