React汉堡配料增减功能报错:Cannot read properties of undefined (reading 'meat')
问题分析与解决方案
错误原因
- 状态丢失:初始状态中包含
INGREDIENT_PRICES常量,但每次调用setState时仅传入ingredients和totalPrice,导致INGREDIENT_PRICES从状态中被覆盖丢失。第二次点击按钮时,state.INGREDIENT_PRICES为undefined,访问其属性时触发报错。 - 闭包陷阱:直接使用
state更新状态时,可能捕获到旧的状态值,在频繁操作时导致状态更新异常。
修复方案
- 将固定不变的
INGREDIENT_PRICES移出状态,作为组件内部常量,避免被状态更新覆盖。 - 使用函数式
setState,确保每次更新都基于最新的状态值,解决闭包问题。 - 为移除操作添加数量判断,防止配料数量变为负数。
修改后的代码
import { useState } from "react"; import Burger from "./Burger/Burger"; import BurgerControls from "./BurgerControls/BurgerControls"; import BootstrapNavbar from "../ReactBootsrap/BootstrapNavbar"; // 将价格常量移出状态 const INGREDIENT_PRICES = { salad: 0.25, cheese: 0.5, meat: 5, bacon: 1, }; export default function BurgerBuilder() { const [state, setState] = useState({ ingredients: { meat: 1, salad: 1, cheese: 1, bacon: 1, }, totalPrice: 0, }); const addIngredientsHandler = (type) => { // 使用函数式setState获取最新状态 setState(prevState => { const oldCount = prevState.ingredients[type]; const updatedCount = oldCount + 1; const updatedIngredients = { ...prevState.ingredients, }; updatedIngredients[type] = updatedCount; const showPrice = INGREDIENT_PRICES[type]; const newPrice = prevState.totalPrice + showPrice; return { ...prevState, ingredients: updatedIngredients, totalPrice: newPrice }; }); }; const removeIngredientsHandler = (type) => { setState(prevState => { const oldCount = prevState.ingredients[type]; // 防止数量变为负数 if (oldCount <= 0) return prevState; const updatedCount = oldCount - 1; const updatedIngredients = { ...prevState.ingredients, }; updatedIngredients[type] = updatedCount; const showPrice = INGREDIENT_PRICES[type]; const newPrice = prevState.totalPrice - showPrice; return { ...prevState, ingredients: updatedIngredients, totalPrice: newPrice }; }); }; return ( <> <BootstrapNavbar /> <Burger ingredients={state.ingredients} /> <BurgerControls addIngredients={addIngredientsHandler} removeIngredients={removeIngredientsHandler} totalprice={state.totalPrice} /> </> ); }
BurgerControls组件无需修改,保持原代码即可。
内容的提问来源于stack exchange,提问作者Mirzaei
相关产品推荐
相关产品推荐

