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

React useState无法更新Ant Design模态框表单变量求助

问题分析与解决方案

问题出在两个核心点:

  • 闭包捕获旧值:Modal.confirm是在onDeleteClick调用时创建的,onOk和Radio.Group捕获的是当时的selectedOption闭包值,后续setSelectedOption更新状态后,Modal内部不会重新渲染,也拿不到最新的state。
  • 重复控制选中状态:Radio组件手动设置了checked属性,和Radio.Group的value属性冲突,导致单选切换异常。

修复方案一:使用useRef跟踪最新选中值

适合继续用Modal.confirm静态方法的场景:

const Signatures = () => {
  // 用ref保存最新值,避免闭包问题
  const selectedOptionRef = useRef('deleteSignature');
  const [selectedOption, setSelectedOption] = useState('deleteSignature');

  const handleDeleteOptionsChange = (event) => {
    const value = event.target.value;
    setSelectedOption(value);
    selectedOptionRef.current = value; // 同步更新ref
  };

  const onDeleteClick = (id) => {
    Modal.confirm({
      okText: 'Confirm',
      centered: true,
      title: 'To Delete this documents, press \'Confirm\'',
      content: (
        <Radio.Group onChange={handleDeleteOptionsChange} value={selectedOption}>
          {/* 去掉Radio上的checked属性,由Group的value统一控制 */}
          <Radio value="deleteSignature">Delete signature request</Radio>
          <Radio value="deleteSignatureAndDocument">Delete signature request and document</Radio>
        </Radio.Group>
      ),
      onOk: async () => {
        // 读取ref的current值,拿到最新选中项
        if (selectedOptionRef.current === 'deleteSignature') {
          return onDeleteSignature(id);
        } else {
          return onDelete(id);
        }
      },
    });
  };

  // ...其他代码
  return (/* ... */);
};
export default Signatures;

修复方案二:改用组件式Modal(推荐)

组件式Modal会随state变化重新渲染,彻底解决闭包问题:

const Signatures = () => {
  const [selectedOption, setSelectedOption] = useState('deleteSignature');
  const [deleteModalVisible, setDeleteModalVisible] = useState(false);
  const [currentDeleteId, setCurrentDeleteId] = useState(null);

  const handleDeleteOptionsChange = (event) => {
    setSelectedOption(event.target.value);
  };

  const onDeleteClick = (id) => {
    setCurrentDeleteId(id);
    setDeleteModalVisible(true);
  };

  const handleOk = async () => {
    setDeleteModalVisible(false);
    if (selectedOption === 'deleteSignature') {
      return onDeleteSignature(currentDeleteId);
    } else {
      return onDelete(currentDeleteId);
    }
  };

  return (
    <>
      {/* 其他页面内容 */}
      <Modal
        visible={deleteModalVisible}
        title="To Delete this documents, press 'Confirm'"
        okText="Confirm"
        centered
        onOk={handleOk}
        onCancel={() => setDeleteModalVisible(false)}
      >
        <Radio.Group onChange={handleDeleteOptionsChange} value={selectedOption}>
          <Radio value="deleteSignature">Delete signature request</Radio>
          <Radio value="deleteSignatureAndDocument">Delete signature request and document</Radio>
        </Radio.Group>
      </Modal>
    </>
  );
};
export default Signatures;

关键说明

  1. 移除Radio的checked属性:Radio.Group的value已经足够控制选中状态,手动设置checked会导致状态不一致。
  2. 闭包问题解决:
    • 方案一用useRef保存最新值,因为ref的current属性是可变的,不会被闭包捕获旧值。
    • 方案二用组件式Modal,Modal的内容会随selectedOption的变化重新渲染,onOk也能拿到最新的state值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 06:50:31