问题描述
在这里,我正在尝试建立一个餐厅网站。我已经构建了它的一半。但我在某个时候卡住了。我收到错误。我无法在我的代码中找出问题所在。每当我尝试通过单击添加按钮添加新食物然后我得到类型错误:无法分配给对象“#”的只读属性“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);