React中如何在promise.then()内正确使用useState?
问题分析与解决方案
核心问题
你的代码存在异步时序不匹配的问题:点击按钮时会同时触发getRules()(异步API请求)和setModalVisible(true)(立即打开模态框)。此时API请求还未返回,rules仍为初始值<h1>hi</h1>,模态框打开后显示的就是这个初始内容。虽然后续API返回后会调用setRules()更新状态,但如果用户没注意到后续更新,就会看起来始终显示初始内容。
另外你的代码存在一个语法错误:const [rules, setRules] React.useState(<h1>hi</h1>); 缺少赋值符号=,正确写法是const [rules, setRules] = React.useState(<h1>hi</h1>);。
解决方案一:等待API返回后再打开模态框
这种方式能确保模态框打开时直接显示正确内容,适合对内容加载速度有信心的场景:
const [rules, setRules] = React.useState(<h1>hi</h1>); const [modalVisible, setModalVisible] = React.useState(false); const getRules = () => { apicall.promise().then((res) => { var rules = null; // ... 处理res的逻辑 rules = <h1>hello</h1>; // ... return rules; }).then((rulesComp) => { setRules(rulesComp); setModalVisible(true); // 拿到内容后再打开模态框 }); } const SvgButton = ({node}: any) => { return ( <foreignObject x="0" y="0" width="20" height="20"> <div onClick={() => getRules()}> <mySVG /> </div> </foreignObject> ) } return ( <> <div> <SvgButton /> is shown here </div> <Modal onDismiss={() => setModalVisible(false)} visible={modalVisible} closeAriaLabel="Close modal" footer="Modal footer" header="Modal title" > {rules} </Modal> </> );
解决方案二:先打开模态框,显示加载状态
这种方式用户体验更好,不会让用户等待太久,先显示加载提示,API返回后自动更新内容:
const [rules, setRules] = React.useState(<div>加载中...</div>); const [modalVisible, setModalVisible] = React.useState(false); const getRules = () => { apicall.promise().then((res) => { var rules = null; // ... 处理res的逻辑 rules = <h1>hello</h1>; // ... return rules; }).then((rulesComp) => { setRules(rulesComp); }); } const SvgButton = ({node}: any) => { return ( <foreignObject x="0" y="0" width="20" height="20"> <div onClick={() => { setRules(<div>加载中...</div>); // 重置为加载状态 getRules(); setModalVisible(true); }}> <mySVG /> </div> </foreignObject> ) } return ( <> <div> <SvgButton /> is shown here </div> <Modal onDismiss={() => setModalVisible(false)} visible={modalVisible} closeAriaLabel="Close modal" footer="Modal footer" header="Modal title" > {rules} </Modal> </> );
内容的提问来源于stack exchange,提问作者chung
相关产品推荐
相关产品推荐

