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

Formik表单onChange事件中如何获取input.value并实现实时字符校验替换

Formik 表单实时替换输入非法字符实现方案

核心思路是重写输入框的onChange事件,先对输入值做格式化处理,再手动同步到Formik的状态中,不会破坏Formik原有校验、提交逻辑。

第一步:修改通用FormInput组件

新增可选的formatFunc入参,用于传入自定义的格式化函数,适配不同字段的处理需求,修改后代码如下:

import React from 'react';
import { ErrorMessage, useField, useFormikContext } from 'formik';
import './formInput.scss';

const FormInput = ({label='', placeholder=null, classNames='', formatFunc, ...props}) => {
    const [field, meta] = useField(props);
    const { setFieldValue, setFieldTouched } = useFormikContext();
    
    const handleChange = async (e) => {
        let inputValue = e.target.value;
        // 若传入格式化函数则预处理输入值
        if (typeof formatFunc === 'function') {
            inputValue = formatFunc(inputValue);
        }
        // 同步处理后的值到Formik状态
        await setFieldValue(field.name, inputValue);
        // 标记字段已触碰,实时触发校验提示
        setFieldTouched(field.name, true, false);
    };

    return (
        <div className="form__input-wrapper">
            <label htmlFor={field.name}>{label}</label>
            <input
                className={`${classNames}`}
                {...props}
                name={field.name}
                value={field.value || ''}
                onChange={handleChange}
                onBlur={field.onBlur}
            />
            {meta.touched && meta.error ? (<div>{meta.error}</div>) : null}
        </div>
    )
}

export default FormInput;

第二步:给需要格式化的字段传入处理函数

以手机号字段只允许输入数字为例,注意你用到的替换正则要加g全局标识符,否则只会替换第一个非数字字符:

<FormInput
    label="手机号"
    name="phone"
    type="phone"
    formatFunc={(str) => str.replace(/\D/g, '')} 
/>

其他字段如果有不同的格式化需求,传入对应处理函数即可,无需修改组件本身。

注意事项

  • Formik的initialValues要确保每个字段都有初始值(比如空字符串),否则输入时可能出现非受控组件报错
  • 原有Yup校验逻辑无需修改,预处理后的值会正常走你定义的校验规则
  • 如果不需要实时触发校验提示,可以删除setFieldTouched那行代码,等用户失焦再显示错误

内容的提问来源于stack exchange,提问作者Wells

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:21:02