微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ReactJs:TypeError:无法分配给对象“#<Object>”的只读属性“cartHandler”?

如何解决ReactJs:TypeError:无法分配给对象“#<Object>”的只读属性“cartHandler”?

在这里,我正在尝试建立一个餐厅网站。我已经构建了它的一半。但我在某个时候卡住了。我收到错误。我无法在我的代码中找出问题所在。每当我尝试通过单击添加按钮添加新食物然后我得到类型错误:无法分配给对象“#”的只读属性“cartHandler”?..多次。有人可以看看吗?

这是我的 App.js 文件

import logo from './logo.svg';
import {
  browserRouter as Router,Switch,Route,Link
} from "react-router-dom";
import './App.css';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css'
import Banner from './components/Banner/Banner';
import Header from './components/Header/Header';
import Foods from './components/Foods/Foods';
import Features from './components/Features/Features';
import Footer from './components/Footer/Footer';
// import SIgnUp from './components/SignUp/SIgnUp';
import NotFound from './components/NotFound/NotFound';

import FoodItemDetails from './components/FoodItemDetails/FoodItemDetails'
import { createContext,useContext,useState } from 'react';
import Login from './components/Login/Login';


export const userContext = createContext();

function App() {

  const [cart,setCart] = useState([]);
  const [orderId,setorderId] = useState(null);
  
  const [deliveryDetails,setDeliveryDetails] = useState({
    todoor:null,road:null,flat:null,businessname:null,address: null
  });

  const [userEmail,setUserEmail] = useState(null);
  const deliveryDetailsHandler = (data) => {
      setDeliveryDetails(data)
  }
  const getUserEmail = (email) => {
    setUserEmail(email);
  }

  const clearCart =  () => {
    const orderedItems = cart.map(cartItem => {
      return {food_id : cartItem.id,quantity: cartItem.quantity}
    })

    const orderDetailsData = { userEmail,orderedItems,deliveryDetails }
    fetch('https://red-onion-backend.herokuapp.com/submitorder',{
        method : "POST",headers: {
            "Content-type" : "application/json"
        },body : JSON.stringify(orderDetailsData)
    })
    .then(res => res.json())
    .then(data=> setorderId(data._id))
    console.log(orderId);

    setCart([])
  }

  const cartHandler = (data) => {
    const alreadyAdded = cart.find(crt => crt.id == data.id );
    const newCart = [...cart,data]
    setCart(newCart);
    if(alreadyAdded){
      const reamingCarts = cart.filter(crt => cart.id != data);
      setCart(reamingCarts);
    }else{
      const newCart = [...cart,data]
      setCart(newCart);
    }
   
  }

  const checkOutItemHandler = (productId,productQuantity) => {
    const newCart = cart.map(item => {
      if(item.id == productId){
          item.quantity = productQuantity;
      }
      return item;
    })

    const filteredCart = newCart.filter(item => item.quantity > 0)
    setCart(filteredCart)
  }
 




  const [logggedInUser,setLoggedInUser] = useState({});
  const [signOutUser,setSignOutUser] = useState({});
  return (
    <userContext.Provider value={([logggedInUser,setLoggedInUser],[signOutUser,setSignOutUser])}>
         <Router>
    <div className="App">
    <Switch>
      <Route exact path="/">

      <Header></Header>
      <Banner></Banner>
      <Foods></Foods>
      <Features></Features>
      <Footer></Footer>
      </Route>
      <Route path="/user">
        <Login></Login>

      </Route>
      <Route path= "/food/:id">
        <Header cart={cart}></Header>
         
         
         {/* <FoodItemDetails cart={cart} cartHandler={cartHandler}></FoodItemDetails> */}
         <FoodItemDetails cart={cart} cartHandler={cartHandler}></FoodItemDetails>
         <Footer></Footer>

      </Route>
      <Route path ="*">
        <NotFound></NotFound>
      </Route>

    </Switch>
    </div>
    </Router>
     </userContext.Provider>
 
  );
}

export default App;

这是我的 FoodItemDetails.js 文件

import React,{ useEffect,useState } from "react";
import { useParams } from "react-router";
// import { useParams } from "react-router";
// import PreLoader from "../PreLoader/PreLoader";
import { FontAwesomeIcon} from '@fortawesome/react-fontawesome'
import { faCartArrowDown,faCheckCircle } from '@fortawesome/free-solid-svg-icons' 
import PreLoader from "../PreLoader/PreLoader";


const FoodItemDetails = (props) => {
  // const {name,shortDescription,price,images} = props.food;

  console.log(props,"nashir")
  const [currentFood,setCurrentFood] = useState({});
  const {id} = useParams();
  console.log(id);
  const [quantity,setQuantity] = useState(1);
  const [isSuccess,setIsSuccess] = useState(false);
  const [selectedBigImage,setSelectedBigImage] = useState(null);
  const [preloaderVisibility,setPreloaderVisibility] = useState("block");
  // const [quantity,setQuantity] = useState(1);
  

  

  useEffect(() => {
    fetch("https://red-onion-backend.herokuapp.com/food/" + id)
      .then((res) => res.json())
      .then((data) => {
        setCurrentFood(data);
        setPreloaderVisibility("none");
      })
      .catch((err) => console.log(err));
    if (currentFood.images) {
      setSelectedBigImage(currentFood.images[0]);
    }
    window.scrollTo(0,0);
  },[currentFood.name]);
  const finalCartHandler = (currentFood) => {
    currentFood.quantity = quantity;
    console.log(currentFood,'food man');
    props.cartHandler = currentFood;
    setIsSuccess(true);
    console.log(isSuccess,"what");
  }
  if(isSuccess){
    setTimeout(() => {

      setIsSuccess(false)
      console.log(isSuccess);
    },1500);
  }

  return (
    <div className="food-details container my-5">
      <PreLoader visibility={preloaderVisibility}></PreLoader>
      {currentFood.name && (
        <div className="row">
          <div className="col-md-6 my-5">
            <h1>{currentFood.name}</h1>
            <p className="my-5">{currentFood.fullDescription}</p>
            <div className="d-flex my-4">
              <h2>${currentFood.price.toFixed(2)}</h2>
              <div className="cart-controller ml-3">
                <button
                  className="btn"
                  onClick={() => setQuantity(quantity <= 1 ? 1 : quantity - 1)}
                >
                  -
                </button>
                <button
                  className="btn"
                  onClick={() => setQuantity(quantity + 1)}
                >
                  +
                </button>
              </div>
            </div>
            <div className="action d-flex align-items-center">
                <button className="btn btn-danger btn-rounded" onClick={() => finalCartHandler(currentFood)}><FontAwesomeIcon  icon={faCartArrowDown} /> Add</button>
            </div>
            <div className="more-images mt-5">
              {currentFood.images.map((img,index) => (
                <img
                  onClick={() => setSelectedBigImage(currentFood.images[index])}
                  className={
                    currentFood.images[index] === selectedBigImage
                      ? "mr-4 small-img active-small-img"
                      : "mr-4 small-img"
                  }
                  height="150px"
                  src={img}
                  alt=""
                />
              ))}
            </div>
          </div>
          <div className="col-md-6 my-5">
            <img src={selectedBigImage} className="img-fluid" alt="" />
          </div>
        </div>
      )}
    </div>
  );
};

export default FoodItemDetails;
 

解决方法

道具是只读属性。在 finalCartHandler 中,您试图将 props.cartHandler 分配给 currentFood。我假设您想调用 props.cartHandler 而不是分配它。

我还注意到在 cartHandler 内部,您正在检查 id 是否与 == 相同,后者是一个真/假等号,而 === 会更好地工作(也在少数其他带有 ==!= 的点)。

,

首先你不能改变道具的属性。它们是只读属性。

第二您的 cartHnadler 是函数而不是属性,但您正在分配值而不是调用函数。

props.cartHandler = currentFood;   // here you are assigning value

要解决这个问题,您需要调用 cartHandler 并将 currentFood 作为参数传递,如下所示:-

props.cartHandler(currentFood);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。