如何让Formik仅在点击type="submit"按钮时触发提交与校验?
解决Formik第三方组件按钮误触提交的问题
核心问题
第三方组件内的按钮未设置type="button",默认会触发表单的submit事件,进而让Formik自动标记所有字段为touched。我们需要拦截非目标按钮触发的提交行为,仅允许真正的提交按钮触发Formik的提交逻辑。
方案一:通过表单提交事件判断触发源
直接在Form组件上自定义提交处理逻辑,仅当触发提交的是我们指定的按钮时,才执行Formik的handleSubmit:
<Form onSubmit={(e) => { // 验证触发提交的按钮是否为目标提交按钮 const targetBtn = e.submitter; // 可通过按钮文本、id、类名等特征精准判断 if (targetBtn?.id === 'form-submit-btn') { props.handleSubmit(e); } else { // 非目标按钮,阻止默认提交行为 e.preventDefault(); } }}> <div className="row"> {/* 第三方组件 */} <SomethirdpartyLibWhichContainsButton /> </div> <div className="d-flex flex-row-reverse mx-3"> <div> {/* 给目标提交按钮加唯一id用于判断 */} <button id="form-submit-btn" className="btn btn-primary" type="submit">Submit</button> </div> </div> </Form>
方案二:事件委托拦截第三方按钮点击
如果能识别第三方组件内按钮的特征,可在其父容器上通过事件委托阻止按钮的默认行为:
<div className="row" onClick={(e) => { const clickedBtn = e.target.closest('button'); if (clickedBtn) { // 排除我们的提交按钮,拦截其他按钮的默认行为 const isOurSubmitBtn = clickedBtn.classList.contains('btn-primary'); if (!isOurSubmitBtn) { e.preventDefault(); // 若第三方按钮需执行原有逻辑,可在此手动调用组件提供的回调(如有) } } }}> <SomethirdpartyLibWhichContainsButton /> </div>
方案三:修改Formik的触摸行为(不推荐)
如果不需要提交时自动标记所有字段为touched,可关闭Formik的默认触摸配置:
<Formik initialValues={initialValues} validationSchema={validationSchema} onSubmit={(values, actions) => { console.log("submit", { values, actions }); }} enableReinitialize={true} // 关闭提交时自动标记所有字段为touched touchOnSubmit={false} > {/* 表单内容 */} </Formik>
注意:此方案会影响正常提交时的错误提示逻辑,仅适合不需要全字段错误提示的场景。
内容的提问来源于stack exchange,提问作者Sanjeet kumar
相关产品推荐
相关产品推荐

