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

React表单单选按钮selectedOption值错误、price状态不更新问题咨询

问题根因

  • React 中 useState 返回的状态更新函数是异步批量执行的:调用setSelectedOption后,当前函数作用域内的selectedOption变量不会立即更新,仍为更新前的旧值,所以你直接打印、传值给handlePriceChange拿到的都是上一次的状态,就会出现点medium打印small、price不更新的问题。
  • 第三个「big」尺寸的单选框onChange回调里漏写了handlePriceChange调用,选择大尺寸时完全不会触发价格更新逻辑。

修复方案

方案1:直接使用事件对象里的最新值(快速修复)

不要用当前作用域的旧selectedOption,直接取e.target.value作为最新值传递即可,同时补全big尺寸的价格更新调用:

// 三个单选框的onChange统一修改为如下逻辑
onChange={(e) => {
  const currentVal = e.target.value;
  setSelectedOption(currentVal);
  console.log(currentVal); // 直接用最新取到的值
  handlePriceChange(currentVal); // 传最新值更新价格
}}

方案2:优化状态逻辑(更易维护,避免同步问题)

price和size本质都是根据selectedOption派生的计算值,完全不需要单独维护state,直接实时计算即可,删掉多余的状态和更新逻辑,从根源避免不同步问题:

import React from "react";
import pizzaStore from "./stores/PizzaStore";
import { observer } from "mobx-react-lite";
import cartStore from "./stores/CartStore";

function ModalWindowComponent({ activeModal, setActiveModal }: any) {
  const [selectedOption, setSelectedOption] = React.useState("small");

  const setClose = () => {
    setSelectedOption("small");
    setActiveModal(false);
  };

  // 直接派生计算price和size,不需要额外state和更新函数
  const fixedSize = pizzaStore.size;
  const size =
    selectedOption === "small"
      ? fixedSize
      : selectedOption === "medium"
      ? fixedSize * 1.5
      : fixedSize * 2;
  const price =
    selectedOption === "small"
      ? pizzaStore.modalProps.price
      : selectedOption === "medium"
      ? pizzaStore.modalProps.price * 1.5
      : pizzaStore.modalProps.price * 2;

  const obj = {
    modalName: pizzaStore.modalProps.name,
    modalDesc: pizzaStore.modalProps.description,
    modalSize: size,
    modalPrice: price,
    modalImage: pizzaStore.modalProps.imageUrl,
  };
  return (
    <div
      className={activeModal ? "modal active" : "modal"}
      onClick={() => {
        setActiveModal(false);
        setSelectedOption("small");
      }}
    >
      <div
        className="modal-content"
        onClick={(e) => {
          e.stopPropagation();
        }}
      >
        <div className="modal-content-header">
          <button onClick={() => setClose()}>Close</button>
        </div>
        <img
          src={pizzaStore.modalProps.imageUrl}
          className="modal-content-img"
        />
        <p className="modal-content-pizza-name">{pizzaStore.modalProps.name}</p>
        <p className="modal-content-pizza-desc">
          {pizzaStore.modalProps.description}
        </p>
        <p className="modal-content-pizza-size">{size}см</p>
        <p className="modal-content-pizza-weight">
          {pizzaStore.setWeight(selectedOption)}грамм
        </p>
        <p className="modal-content-pizza-price">{price}Руб.</p>
        <form
          className="modal-content-sizes-form"
          onSubmit={(e: any) => {
            cartStore.handleSubmitForm(e, obj);
          }}
        >
          <label>
            <input
              name="radio-size"
              value="small"
              type="radio"
              onChange={(e) => {
                setSelectedOption(e.target.value);
              }}
              checked={selectedOption === "small"}
              className="modal-content-sizes-form-option"
            />
            Маленькая
          </label>
          <label>
            <input
              name="radio-size"
              value="medium"
              type="radio"
              onChange={(e) => {
                setSelectedOption(e.target.value);
              }}
              checked={selectedOption === "medium"}
              className="modal-content-sizes-form-option"
            />
            Средняя
          </label>
          <label>
            <input
              name="radio-size"
              value="big"
              type="radio"
              onChange={(e) => {
                setSelectedOption(e.target.value);
              }}
              checked={selectedOption === "big"}
              className="modal-content-sizes-form-option"
            />
            Большая
          </label>
          <button
            onClick={() => {
              setClose();
              console.log(cartStore.cartItems);
            }}
          >
            Добавить
          </button>
        </form>
      </div>
    </div>
  );
}

export default observer(ModalWindowComponent);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 11:12:01