我有一个小型餐厅应用,它可以呈现菜单并让用户下订单。父组件接收一组菜单项并为每个项呈现一个子组件。每个项目的数量在子组件('menu-item')中初始化,并且也保存在本地存储中,因此如果用户刷新页面,订单仍然存在。提交订单后,本地存储由父组件清除,但此更改不会被子组件接收。因此,即使在提交订单后,用户仍会看到订单数量。我想在提交订单后将订单数量重置为0。以下是精简代码库。
//父母
const TotalStore = {
total: 0,
reset_timer: setTimeout(() => {}, 0),
compute() {
let newTotal = 0;
let types = new Map<string, boolean>();
TotalStore.items.forEach((value: TotalStoreMenuItem) => {
newTotal += value.price * value.count;
types.set(value.type, true);
});
if (TotalStore.total !== newTotal) {
clearTimeout(TotalStore.reset_timer);
TotalStore.reset_timer = setTimeout(() => {
TotalStore.total = newTotal;
TotalStore.onChange(newTotal);
}, 50);
}
},
update(id: number, price: number, count: number, type: string) {
TotalStore.items.set(id, {
id,
price,
count,
type,
});
TotalStore.compute();
},
reset() {
TotalStore.items.clear();
localStorage.clear();
TotalStore.total = 0;
},
onChange(t: number) {},
items: new Map<number, TotalStoreMenuItem>(),
};
const itemChanged = (
id: number,
price: number,
count: number,
type: string
) => {
TotalStore.update(id, price, count, type);
};
useEffect(() => {
apiFetch("menu").then((json) => setMenu(json.menu));
}, []);
async function handleSubmit(e: any) {
e.preventDefault();
const selectedItems = getSelectedItems(TotalStore);
apiFetch("order", "post", { selectedItems })
.then((json) => {
alert("Order has been submitted");
TotalStore.reset();
}
return (
<div>
{menu.length > 0 ? (
<>
<div className="menu">
<div className="menu-title">Food Menu</div>
<form id="menu-form" onSubmit={handleSubmit} autoComplete="off">
<Menu onChange={itemChanged} props={menu} />
<button type="submit" disabled={!orderPlaced(total)}>
Place Order
</button>
</form>
</div>
<div className="order-total">
<h2>
Total: $<span>{total.toFixed(2)}</span>
</h2>
</div>
</>
) : (
<>Loading Menu</>
)}
</div>
);
//菜单
export default function Menu({ onChange, props }: MenuProps) {
return (
<div>
{props.map((food: any, index: number) => {
return (
<MenuItem
key={index}
onChange={onChange}
type={food.type}
item={food}
/>
);
})}
</div>
);
}
//菜单项
const FoodItemLocalStore = {
setCount(id: Number, count: Number) {
localStorage.setItem(`menu_item_id_${id}`, String(count));
},
getCount(id: Number) {
return parseInt(localStorage.getItem(`menu_item_id_${id}`) || "0");
},
};
export default function MenuItem({ onChange, item, type }: MenuItemProps) {
const [data, setData] = useState({
count: FoodItemLocalStore.getCount(item.id),
});
const menuItemCountChange = (e: any) => {
data.count = parseInt(e.target.value);
FoodItemLocalStore.setCount(item.id, data.count);
setData({ ...data });
};
onChange(item.id, item.price, data.count, type);
return (
<div>
<article className="menu-item" data-item-type={type}>
<h3 className="item-name">{item.name}</h3>
<input
type="number"
className="menu-item-count"
min="0"
value={data.count}
onChange={menuItemCountChange}
/>
<strong className="item-price">${item.price.toFixed(2)}</strong>
</article>
</div>
);
}