ReactJS中子表单位于模态框内时如何禁用提交按钮
解决方案
你需要把Formik的isSubmitting状态同步到模态框的按钮组件上,以下是具体修改步骤:
1. 修复表单提交逻辑的错误
首先修正CountryForm组件里的提交函数,你原来的代码里拼写错误了catch方法,并且注释了setSubmitting的调用,会导致提交状态无法重置:
// CountryForm 组件的 _onSubmit 方法 function _onSubmit(fields, { setSubmitting }) { return fetch(countryService.insertCountry(fields)) .then(() => { setSubmitting(false); // 放开注释,重置提交状态 handleClose(); setRecords(countryService.getCountries()); setNotify({ isOpen: true, message: `Added successfully`, type: "success" }); }) .catch((err) => { // 修正拼写错误 cath → catch alert(err); setSubmitting(false); // 放开注释,异常场景也重置提交状态 }); }
2. 改造Popup组件支持自定义操作按钮
因为按钮现在写在Popup组件里,拿不到Form的提交状态,我们给Popup增加自定义按钮的插槽:
// Popup 组件修改 function Popup(props) { const classes = useStyles(); // 新增actions参数接收自定义按钮 const { title, children, openPopup, setOpenPopup, actions, ...rest } = props; return ( <Dialog {...rest} open={openPopup} maxWidth="sm" classes={{ paper: classes.dialogWrapper }} > <DialogTitle dividers="true" className={classes.dialogTitle}> <div style={{ display: "flex" }}> <Typography variant="h4" component="div" style={{ flexGrow: 1 }}> Country </Typography> </div> </DialogTitle> <Divider /> <DialogContent direction="row">{children}</DialogContent> <DialogActions> <Grid container className={classes.buttonsContainer}> <Box className={classes.buttons}> {/* 优先使用传入的自定义按钮,没有就走默认逻辑 */} {actions || ( <> <Button className={classes.button} variant="contained" color="primary" type="submit" form="form" > Save </Button> <Button className={classes.button} color="default" fullWidth onClick={() => setOpenPopup(false)} > Cancel </Button> </> )} </Box> </Grid> </DialogActions> </Dialog> ); }
3. 在Countries组件新增按钮状态管理
增加状态存储自定义按钮,传入Popup和CountryForm:
// Countries 组件新增状态 const [popupActions, setPopupActions] = useState(null); // 渲染组件时传入对应props return ( {/* 其他代码不变 */} <Popup openPopup={openPopup} setOpenPopup={setOpenPopup} actions={popupActions} > <CountryForm handleClose={handleClose} setRecords={setRecords} setNotify={setNotify} setPopupActions={setPopupActions} /> </Popup> {/* 其他代码不变 */} )
4. 在CountryForm里生成带禁用状态的按钮
在Formik的渲染回调里可以直接拿到isSubmitting状态,生成带禁用逻辑的按钮传给上层:
// CountryForm 组件的Formik渲染回调部分 {({ errors, touched, isSubmitting }) => { // 生成带禁用状态的按钮,传给Popup props.setPopupActions( <> <Button className={classes.button} variant="contained" color="primary" type="submit" form="form" disabled={isSubmitting} // 提交中禁用按钮 > {isSubmitting ? "提交中..." : "Save"} </Button> <Button className={classes.button} color="default" fullWidth onClick={props.handleClose} disabled={isSubmitting} // 提交中禁用取消按钮 > Cancel </Button> </> ) return ( {/* 原有Form内容不变 */} ) }}
完成以上修改后,表单提交过程中两个按钮都会自动禁用,提交完成或异常后自动恢复可点击状态。
内容的提问来源于stack exchange,提问作者Cleiton Freitas
相关产品推荐
相关产品推荐

