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;
关键说明
- 移除
Radio的checked属性:Radio.Group的value已经足够控制选中状态,手动设置checked会导致状态不一致。 - 闭包问题解决:
- 方案一用
useRef保存最新值,因为ref的current属性是可变的,不会被闭包捕获旧值。 - 方案二用组件式Modal,Modal的内容会随
selectedOption的变化重新渲染,onOk也能拿到最新的state值。
- 方案一用
内容的提问来源于stack exchange,提问作者Sara N
相关产品推荐
相关产品推荐

