使用外部state的Formik表单提交时字段值为空的问题
问题解决:Formik提交时外部state绑定的字段值为空
问题原因
你手动给Field设置了value={currentPhoneNumber}和自定义onChange,这会脱离Formik的内部状态管理机制。Formik的values对象只跟踪它自己内部维护的字段状态,你更新外部state后并没有同步到Formik的内部状态,所以提交时values.phoneNumber还是初始值(空字符串)。enableReinitialize仅在initialValues变化时重新初始化Formik状态,这里你的initialValues没改动,所以不起作用。
解决方案
方案1:同步外部state与Formik内部状态
在自定义onChange中,同时更新外部state和Formik的字段值,确保两边状态一致:
const [currentPhoneNumber, setCurrentPhoneNumber] = useState("") const submitForm = async (values) => { console.log(values.phoneNumber) // 现在会输出格式化后的值 } <Formik initialValues={initValues} validationSchema={schemas[currentSchemaIndex]} onSubmit={submitForm} enableReinitialize > {({ setFieldValue }) => ( <Form className="py-20 w-100 w-xl-700px px-9" noValidate id="kt_create_account_form" placeholder={undefined} > <Field className="form-control form-control-lg form-control-solid" name="phoneNumber" onChange={(e) => { const asYouType = new AsYouType() const formatted = asYouType.input(e.target.value) // 同时更新外部state和Formik内部字段 setCurrentPhoneNumber(formatted) setFieldValue("phoneNumber", formatted) }} value={currentPhoneNumber} /> </Form> )} </Formik>
方案2:放弃外部state,直接在Formik内部处理格式化
如果外部state不是必须的,直接在Field内部处理格式化,让Formik全程管理状态:
const submitForm = async (values) => { console.log(values.phoneNumber) // 直接拿到格式化后的值 } <Formik initialValues={initValues} validationSchema={schemas[currentSchemaIndex]} onSubmit={submitForm} enableReinitialize > {() => ( <Form className="py-20 w-100 w-xl-700px px-9" noValidate id="kt_create_account_form" placeholder={undefined} > <Field name="phoneNumber"> {({ field }) => ( <input {...field} className="form-control form-control-lg form-control-solid" onChange={(e) => { const asYouType = new AsYouType() const formatted = asYouType.input(e.target.value) // 调用Formik的onChange更新内部状态 field.onChange({ target: { name: field.name, value: formatted } }) }} /> )} </Field> </Form> )} </Formik>
方案3:使用Formik的useField钩子(自定义组件场景)
如果需要封装成自定义组件,可以用Formik的useField钩子来同步状态:
import { useField } from 'formik' const FormattedPhoneNumberField = ({ className }) => { const [field, meta, helpers] = useField('phoneNumber') const handleChange = (e) => { const asYouType = new AsYouType() const formatted = asYouType.input(e.target.value) helpers.setValue(formatted) } return ( <input {...field} className={className} onChange={handleChange} /> ) } // 在Formik中使用 <Formik ...> {() => ( <Form ...> <FormattedPhoneNumberField className="form-control form-control-lg form-control-solid" /> </Form> )} </Formik>
内容的提问来源于stack exchange,提问作者eren
相关产品推荐
相关产品推荐

