我正试图在我的react应用程序中使用useContext钩子来管理cart状态,但我不知道为什么我会一次又一次地收到这个错误,因为我试图破坏的函数是未定义的。
我是使用上下文API的新手,请帮助我。我看到了其他与上下文API相关的答案,并尝试了所有的方法,比如将CartContext导出为默认值,然后在不销毁的情况下导入它,但没有任何效果。我既不能导入函数也不能导入数据。
这是我的CartContext.js文件
import React, { useState, createContext, useReducer } from "react";
import CartReducer from "./CartReducer";
//Initialized Context
export const CartContext = createContext();
export const CartProvider = ({ children }) => {
const [products, setProducts] = useState([]);
const [state, dispatch] = useReducer(CartReducer, products);
function addProductWithQuantity(product) {
dispatch({
type: "ADD_PRODUCT",
payload: {
product,
quantity: 1,
},
});
}
const deleteProductWithId = (id) => {
dispatch({
type: "DELETE_PRODUCT",
payload: id,
});
};
return (
<CartContext.Provider
value={{
state,
addProductWithQuantity,
deleteProductWithId,
}}
>
{children}
</CartContext.Provider>
);
};
这是我使用useContext的文件。
import React, { useContext } from "react";
import {
Card,
Typography,
Tooltip,
IconButton,
Button,
} from "@material-ui/core";
import { Link } from "react-router-dom";
import styles from "./Product.module.css";
import amazon from "../../icons/amazon-brands.png";
import flipkart from "../../icons/flipkart.png";
import { SnackbarProvider, useSnackbar } from "notistack";
import classNames from "classnames";
import { CartContext } from "../../Context/CartContext";
const Product = ({ product }) => {
return (
<SnackbarProvider maxSnack={3} preventDuplicate>
<ProductCard product={product} />
</SnackbarProvider>
);
};
export default Product;
const ProductCard = ({ product }) => {
const {
id,
imageUrls,
storeName,
category,
price,
amazonLink,
flipkartLink,
title,
} = product;
const iconColor = "var(--primaryColor)";
const { addProductWithQuantity } = useContext(CartContext); //Throws an error always
console.log(addProductWithQuantity);
const gotoURL = (location) => {
let a = document.createElement("a");
a.target = "_blank";
a.href = location;
a.click();
};
const handleClickVariant = (variant, title, id) => () => {
enqueueSnackbar(`Successfully added ${title} to cart`, {
variant,
});
onClickHeart(id);
// saveToLocal();
addProductWithQuantity(product);
};
const saveToLocal = () => {
let oldCart = localStorage.getItem("cart");
let newCart = oldCart ? JSON.parse(oldCart) : [];
newCart.push(product);
localStorage.setItem("cart", JSON.stringify(newCart));
};
const onClickHeart = (id) => {
document
.getElementById(id)
.style.setProperty("color", iconColor, "important");
};
const { enqueueSnackbar } = useSnackbar();
return (
<Card key={id} className={styles.card}>
<Link to={`/products/${id.trim()}`} className={styles.noDecoration}>
<div className={styles.thumbnail}>
<img src={imageUrls[0]} alt={title} />
</div>
</Link>
<div className={styles.name}>
<Typography className={styles.category} variant="subtitle2">
{category}
</Typography>
<Link to={`/products/${id.trim()}`} className={styles.noDecoration}>
<Typography className={styles.company} variant="subtitle1">
{title}
</Typography>
</Link>
</div>
<div className={styles.priceLike}>
<h4>₹{price}</h4>
<Tooltip title="Add to favourites" placement="top">
<IconButton
onClick={handleClickVariant("success", title, id)}
className={styles.likeIcon}
>
<i id={id} className={classNames("fas fa-cart-plus")} />
</IconButton>
</Tooltip>
</div>
<div className={styles.buttons}>
<Button
variant="contained"
color="primary"
className={styles.amazonBtn}
onClick={() => gotoURL(amazonLink)}
>
<img src={amazon} alt="amazon-link" /> amazon.in
</Button>
<Button
variant="contained"
color="primary"
className={styles.flipkartBtn}
onClick={() => gotoURL(flipkartLink)}
>
<img src={flipkart} alt="flipkart-link" />
</Button>
</div>
</Card>
);
};
}
问题是我忘记用CartContext Provider包装我的路由。以下是我所做的,
import CartProvider from '../CartContext';
return(
<CartProvider>
... Routes
<CartProvider>
)