You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React JS中如何让同一组件的多个实例拥有独立的状态与功能?

问题核心原因

你定义的Amount变量属于模块级全局变量,放在了FoodItem组件外部,所有页面上渲染的FoodItem实例都会共享这同一个变量,自然操作一个组件的数量就会同步影响其他所有组件。另外你已经声明了amountNumber组件内部状态,但全程没有实际使用,所有读写操作都在操作全局Amount,状态声明完全没有生效。

具体修改步骤

  1. 删除组件外部的全局Amount声明:var Amount = 0;
  2. 给组件内部的amountNumber状态设置初始值0:
const [amountNumber, setAmountNumber] = useState(0);
  1. 改写数量增减逻辑,全部操作组件内部的amountNumber状态,不要用全局变量:
function OnclickAddToAmount() {
  setAmountNumber(prev => prev + 1);
}
function OnclickRemoveFromAmount() {
  setAmountNumber(prev => prev - 1);
}
  1. 把JSX模板中所有用到Amount的位置,全部替换为amountNumber

修改后完整代码

import React, { useState } from "react";

function FoodItem(props) {
  const [mainDivActivated, mainDivSetStyle] = useState("FoodItemMainContainer");
  const [descriptionDivActivated, descriptionSetStyle] =useState("FoodDescription");
  const [addButtonDivDisplay, addButtonSetStyle] = useState("PositionReletive");
  const [trashButtonDivDisplay, trashButtonSetStyle] = useState("PositionReletive DisplayNone");
  const [amountNumber, setAmountNumber] = useState(0);
  var activate = 0;

  function OnclickAddToAmount() {
    setAmountNumber(prev => prev + 1);
  }
  function OnclickRemoveFromAmount() {
    setAmountNumber(prev => prev - 1);
  }

  function OnclickActivateEvent() {
    activateItem();
    OnclickAddToAmount();
  }
  function activateItem() {
    mainDivSetStyle("FoodItemMainContainer PrimaryBackgroundGradientColor");
    descriptionSetStyle("FoodDescriptionActivated");
    addButtonSetStyle("PositionReletive DisplayNone");
    trashButtonSetStyle("PositionReletive");
  }
  function OnclickDeactivateEvent() {
    deactivateItem();
    OnclickRemoveFromAmount();
  }
  function deactivateItem() {
    mainDivSetStyle("FoodItemMainContainer");
    descriptionSetStyle("FoodDescription");
    addButtonSetStyle("PositionReletive");
    trashButtonSetStyle("PositionReletive DisplayNone");
  }

  return (
    <div className={mainDivActivated}>
      <div className="FoodItemContainer">
        <div>
          <div className="FontSizeXL">{props.foodName}</div>
          <div className={descriptionDivActivated}>{props.foodDescription}</div>
        </div>
        <div className="PositionReletive">
          <img
            className="VerticallyAndHorizontallyCentered FoodMenuImageCss"
            src="/images/temptestpictures/foodImage.jpg"
            alt=""
          />
        </div>
        <div className="PositionReletive FoodItemPriceCss">
          <div className="FontSizeXL">Price : {props.foodPrice}</div>
        </div>
        <div className={addButtonDivDisplay}>
          <div
            onClick={() => OnclickActivateEvent()}
            className="FontSizeXL PrimaryBackgroundGradientColor ColorWhite VerticallyAndHorizontallyCentered WidthFull HorizontallyCenteredText FoodItemAddBtn"
          >
            Add
          </div>
        </div>
        <div className={trashButtonDivDisplay}>
          <div className="VerticallyAndHorizontallyCentered WidthFull HorizontallyCenteredText FoodItemAddBtn">
            <div className="AddOrRemoveFoodIconContainer">
              {amountNumber<2 ? (
                <span onClick={() => OnclickDeactivateEvent()}className="icon-trashcan AddOrRemoveFoodIcon"></span>
              ) : (
                <span onClick={() => OnclickRemoveFromAmount()}className="icon-minus AddOrRemoveFoodIcon"></span>
              )}
              <div className="FontSizeXL AddOrremoveNumber">{amountNumber}</div>
              <span onClick={() => OnclickAddToAmount()}className="icon-plus AddOrRemoveFoodIcon"></span>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
export default FoodItem;

修改后每个FoodItem组件的数量都会存在自己的内部状态里,实例之间完全隔离,不会互相影响。

内容的提问来源于stack exchange,提问作者Damien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 05:45:02