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