You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用外部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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:13:25