无法从上下文中解构对象的属性,因为它是未定义的

时间:2020-07-30 09:40:41

标签: javascript html reactjs react-hooks

我试图在我的应用程序中使用useContext钩子来管理购物车状态,但是我不知道为什么我一次又一次收到此错误,因为我要解构的功能是不确定的。 / p>

我是使用上下文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>
  );
};

}

1 个答案:

答案 0 :(得分:0)

问题是我忘记用 CartContext Provider 包装我的路线。 这是我所做的,

import CartProvider from '../CartContext';

return(
 <CartProvider>
   ... Routes
 <CartProvider>
)