收到标题为“Uncaught TypeError:无法读取未定义的属性(读取“cartFoodItems”)”的错误当点击我的购物车按钮时

发布于 2025-01-17 15:48:53 字数 6059 浏览 0 评论 0原文

我正在开发一个食品应用程序,它将商品添加到购物车然后计算总量。我正在尝试实现一个减速器,而不是拥有多个状态挂钩实例,并且在尝试单击打开我的购物车模式时遇到此错误。

我知道这些物品已成功添加到购物车,因为当我添加它们时,然后在控制台中检查并从我的模式中删除“display:none”属性,然后查看那里添加的食品。由于某种原因,特别是当我单击购物车查看模式时,我收到了错误。

错误消息表明错误位于我的 app.js 文件中,我在其中将定义 cartFoods 属性分配给我的 Cartmodal 组件

App.js 组件

import logo from "./logo.svg";
import "./App.css";
import NavHeader from "./NavHeader";
import { useState, useEffect, useReducer } from "react";
import FoodList from "./FoodList";
import CartModal from "./CartModal";
import "animate.css";

function App() {
  const [foods, setFoods] = useState([
    {
      food: "sushi roll",
      description: "fresh tuna topped with eel sauce and avocado",
      price: "14.99",
      quantity: 1,
    },

    {
      food: "pizza",
      description: "baked to a crisp with mozarrella, basil and tomato sauce",
      price: "9.99",
      quantity: 1,
    },
    {
      food: "special fried rice",
      description: "cooked with onions , shrimp , chicken",
      price: "19.99",
      quantity: 1,
    },
    {
      food: "tacos",
      description:
        "choice of either ,shrimp , chicken, or steak, topped with pico de gallo",
      price: "15.99",
      quantity: 1,
    },
  ]);

  const [totalFoodAmount, setTotalFoodAmount] = useState(0);

  // const [modalDisplay, setModalDisplay] = useState("none");
  const [totalPrice, setTotalPrice] = useState(0);
  const [cartFoods, setCartFoods] = useState([]);
  const [cartItem, setCartItem] = useState({});
  const [modalDisplay, setModalDisplay] = useState("none");
  const [amountValue, setAmountValue] = useState(0);

  function foodReducer(state, action) {
    if (action.type === "ADD_CART_ITEMS") {
      return { cartFoodItems: state.cartFoodItems.concat(action.val) };
    }
  }

  const [foodState, dispatch] = useReducer(foodReducer, {
    modalDisplay: "none",
    totalFoodPrice: 0,
    cartFoodItems: [],
  });

  function setDisplay() {
    dispatch({ type: "ADD_MODAL_DISPLAY" });
    setModalDisplay("flex");
  }
  function removeModal() {
    dispatch({ type: "REMOVE_MODAL_DISPLAY" });
    setModalDisplay("none");
  }

  function setQuantity(e) {
    console.log(e.target.value);
    setAmountValue(e.target.value);
  }
  function addFood(food) {
    console.log(food);
    let newFoodItem = { ...food, quantity: amountValue };
    // setCartFoods((prevState) => cartFoods.concat(newFoodItem));
    dispatch({ type: "ADD_CART_ITEMS", val: newFoodItem });

    // ask slavo specific question on why state doesnt update right away when you console.log(cartFoods) inside the function
  }

  useEffect(() => {
    let total = foodState.cartFoodItems.reduce(function (a, b) {
      return a + Number(b.quantity);
    }, 0);

    setTotalFoodAmount(total);

    foodState.cartFoodItems.map((food) =>
      setTotalPrice(totalPrice + food.price * food.quantity)
    );
  }, [foodState]);

  return (
    <div className="App">
      <NavHeader cartQuantity={totalFoodAmount} setDisplay={setDisplay} />
      <FoodList foodList={foods} addFood={addFood} setAmount={setQuantity} />
      <CartModal
        cartFoods={foodState.cartFoodItems}
        display={modalDisplay}
        closeModal={removeModal}
        totalPrice={totalPrice}
      />
    </div>
  );
}

export default App;

Cart.js 组件

import React from "react";

export default function Cart(props) {
  return (
    <div
      style={{
        display: "flex",
        marginRight: "35px",
        border: "1px solid lightgray",
        padding: "5px",
        borderRadius: "5px",
        margin: "10px",
      }}
      className="cart-section"
      onClick={props.setDisplay}
    >
      <div style={{ marginRight: "20px" }}>
        <h4>Your Cart</h4>
      </div>
      <div style={{ position: "relative", top: "0vh" }}>
        <h4>Quantity: {props.cartQuantity}</h4>
      </div>
    </div>
  );
}

CartModal.js

import React from "react";
import "animate.css";
import { CSSTransition } from "react-transition-group";

export default function CartModal(props) {
  return (
    <div
      style={{
        background: "#000000a6",
        width: "100vw",
        height: "100vh",
        position: "fixed",
        top: "0",
        left: "0",
        overflow: "scroll",
        display: props.display,
        justifyContent: "center",
        alignItems: "center",
      }}
    >
      <div
        style={{
          background: "white",
          padding: "30px",
          minHeight: "60vh",
          minWidth: "75vw",
          borderRadius: "10px",
        }}
        className="cart-modal"
      >
        <div style={{ display: "flex", justifyContent: "flex-end" }}>
          <h3 onClick={props.closeModal}>x</h3>
        </div>
        <h4 style={{ textAlign: "center" }}>Your Cart</h4>

        {props.cartFoods.length === 0 ? (
          <h1>There are no Items in your cart</h1>
        ) : (
          props.cartFoods.map((food, index) => (
            <div
              style={{
                display: "flex",
                justifyContent: "space-between",
                borderBottom: "2px solid lightgray",
              }}
              key={index}
            >
              <div style={{ width: "10vh" }}>
                <h3>{food.food}</h3>
                <p>{food.price}</p>
                <p>Quantity: {food.quantity}</p>
              </div>
              <div style={{ display: "flex" }}>
                <button style={{ margin: "10px", maxHeight: "20px" }}>-</button>
                <button style={{ margin: "10px", maxHeight: "20px" }}>+</button>
              </div>
            </div>
          ))
        )}
        <h2>Price: ${props.totalPrice}</h2>
      </div>
    </div>
  );
}

I am working on a food app that adds items to a cart then calculates the total amount. I am trying to implement a reducer as opposed to having multiple instances of state hooks and I am running into this error when trying to click open my cart modal.

I know the items are being added successfully to the cart because when I add them, then inspect in the console and remove the "display: none " property from my modal and see the added food items there. For some reason its specifically when I click my cart to see the modal is when I receive the error.

The error message is saying the error is located in my app.js file where I assign define the cartFoods prop to my Cartmodal component

App.js Component

import logo from "./logo.svg";
import "./App.css";
import NavHeader from "./NavHeader";
import { useState, useEffect, useReducer } from "react";
import FoodList from "./FoodList";
import CartModal from "./CartModal";
import "animate.css";

function App() {
  const [foods, setFoods] = useState([
    {
      food: "sushi roll",
      description: "fresh tuna topped with eel sauce and avocado",
      price: "14.99",
      quantity: 1,
    },

    {
      food: "pizza",
      description: "baked to a crisp with mozarrella, basil and tomato sauce",
      price: "9.99",
      quantity: 1,
    },
    {
      food: "special fried rice",
      description: "cooked with onions , shrimp , chicken",
      price: "19.99",
      quantity: 1,
    },
    {
      food: "tacos",
      description:
        "choice of either ,shrimp , chicken, or steak, topped with pico de gallo",
      price: "15.99",
      quantity: 1,
    },
  ]);

  const [totalFoodAmount, setTotalFoodAmount] = useState(0);

  // const [modalDisplay, setModalDisplay] = useState("none");
  const [totalPrice, setTotalPrice] = useState(0);
  const [cartFoods, setCartFoods] = useState([]);
  const [cartItem, setCartItem] = useState({});
  const [modalDisplay, setModalDisplay] = useState("none");
  const [amountValue, setAmountValue] = useState(0);

  function foodReducer(state, action) {
    if (action.type === "ADD_CART_ITEMS") {
      return { cartFoodItems: state.cartFoodItems.concat(action.val) };
    }
  }

  const [foodState, dispatch] = useReducer(foodReducer, {
    modalDisplay: "none",
    totalFoodPrice: 0,
    cartFoodItems: [],
  });

  function setDisplay() {
    dispatch({ type: "ADD_MODAL_DISPLAY" });
    setModalDisplay("flex");
  }
  function removeModal() {
    dispatch({ type: "REMOVE_MODAL_DISPLAY" });
    setModalDisplay("none");
  }

  function setQuantity(e) {
    console.log(e.target.value);
    setAmountValue(e.target.value);
  }
  function addFood(food) {
    console.log(food);
    let newFoodItem = { ...food, quantity: amountValue };
    // setCartFoods((prevState) => cartFoods.concat(newFoodItem));
    dispatch({ type: "ADD_CART_ITEMS", val: newFoodItem });

    // ask slavo specific question on why state doesnt update right away when you console.log(cartFoods) inside the function
  }

  useEffect(() => {
    let total = foodState.cartFoodItems.reduce(function (a, b) {
      return a + Number(b.quantity);
    }, 0);

    setTotalFoodAmount(total);

    foodState.cartFoodItems.map((food) =>
      setTotalPrice(totalPrice + food.price * food.quantity)
    );
  }, [foodState]);

  return (
    <div className="App">
      <NavHeader cartQuantity={totalFoodAmount} setDisplay={setDisplay} />
      <FoodList foodList={foods} addFood={addFood} setAmount={setQuantity} />
      <CartModal
        cartFoods={foodState.cartFoodItems}
        display={modalDisplay}
        closeModal={removeModal}
        totalPrice={totalPrice}
      />
    </div>
  );
}

export default App;

Cart.js component

import React from "react";

export default function Cart(props) {
  return (
    <div
      style={{
        display: "flex",
        marginRight: "35px",
        border: "1px solid lightgray",
        padding: "5px",
        borderRadius: "5px",
        margin: "10px",
      }}
      className="cart-section"
      onClick={props.setDisplay}
    >
      <div style={{ marginRight: "20px" }}>
        <h4>Your Cart</h4>
      </div>
      <div style={{ position: "relative", top: "0vh" }}>
        <h4>Quantity: {props.cartQuantity}</h4>
      </div>
    </div>
  );
}

CartModal.js

import React from "react";
import "animate.css";
import { CSSTransition } from "react-transition-group";

export default function CartModal(props) {
  return (
    <div
      style={{
        background: "#000000a6",
        width: "100vw",
        height: "100vh",
        position: "fixed",
        top: "0",
        left: "0",
        overflow: "scroll",
        display: props.display,
        justifyContent: "center",
        alignItems: "center",
      }}
    >
      <div
        style={{
          background: "white",
          padding: "30px",
          minHeight: "60vh",
          minWidth: "75vw",
          borderRadius: "10px",
        }}
        className="cart-modal"
      >
        <div style={{ display: "flex", justifyContent: "flex-end" }}>
          <h3 onClick={props.closeModal}>x</h3>
        </div>
        <h4 style={{ textAlign: "center" }}>Your Cart</h4>

        {props.cartFoods.length === 0 ? (
          <h1>There are no Items in your cart</h1>
        ) : (
          props.cartFoods.map((food, index) => (
            <div
              style={{
                display: "flex",
                justifyContent: "space-between",
                borderBottom: "2px solid lightgray",
              }}
              key={index}
            >
              <div style={{ width: "10vh" }}>
                <h3>{food.food}</h3>
                <p>{food.price}</p>
                <p>Quantity: {food.quantity}</p>
              </div>
              <div style={{ display: "flex" }}>
                <button style={{ margin: "10px", maxHeight: "20px" }}>-</button>
                <button style={{ margin: "10px", maxHeight: "20px" }}>+</button>
              </div>
            </div>
          ))
        )}
        <h2>Price: ${props.totalPrice}</h2>
      </div>
    </div>
  );
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文