如何在Formik的onBlur事件触发时格式化输入框值(以手机号为例)
解决Formik手机号输入框onBlur格式化问题
Hey there! 刚好之前做过类似的需求,给你分享一下具体实现步骤,非常简单~
核心思路
Formik是受控表单,所以不能直接修改输入框的值,必须通过它提供的setFieldValue方法来更新表单状态。我们只需要在输入框失焦(onBlur)时,调用自定义的手机号格式化函数,再把格式化后的结果同步到Formik的字段值里就行。
具体实现步骤
1. 写一个手机号格式化纯函数
先封装一个通用的格式化函数,处理各种输入情况(比如用户输入了非数字字符、不完整的手机号):
const formatPhoneNumber = (rawPhone) => { // 第一步:去掉所有非数字字符,只保留数字 const cleanedPhone = rawPhone.replace(/\D/g, ''); // 第二步:按照国内手机号规则格式化(比如 138 1234 5678) const phoneMatch = cleanedPhone.match(/^(\d{3})(\d{4})(\d{4})$/); if (phoneMatch) { // 匹配成功,返回带空格的格式化字符串 return `${phoneMatch[1]} ${phoneMatch[2]} ${phoneMatch[3]}`; } // 如果是不完整的手机号,返回清理后的纯数字(避免出现奇怪的格式) return cleanedPhone; };
2. 在Formik中绑定onBlur事件
这里分两种场景,分别是用useFormik钩子和Field组件的情况:
场景一:使用useFormik钩子
直接在输入框的onBlur事件里调用格式化函数,并用setFieldValue更新值:
import { useFormik } from 'formik'; const PhoneForm = () => { const formik = useFormik({ initialValues: { phone: '' }, onSubmit: (values) => { // 提交时记得把格式化后的手机号转成纯数字(如果后端需要) const submitPhone = values.phone.replace(/\s/g, ''); console.log('提交的手机号:', submitPhone); // 这里写你的表单提交逻辑 }, }); return ( <form onSubmit={formik.handleSubmit}> <input type="text" name="phone" value={formik.values.phone} onChange={formik.handleChange} onBlur={() => { const formattedPhone = formatPhoneNumber(formik.values.phone); formik.setFieldValue('phone', formattedPhone); }} placeholder="请输入手机号" /> <button type="submit">提交</button> </form> ); };
场景二:使用Formik的Field组件
如果项目里用了Field组件,可以通过useFormikContext获取setFieldValue,或者直接给Field传onBlur属性:
import { Form, Field, useFormikContext } from 'formik'; // 封装一个自定义手机号输入组件 const CustomPhoneInput = () => { const { values, setFieldValue } = useFormikContext(); const handleBlur = () => { const formattedPhone = formatPhoneNumber(values.phone); setFieldValue('phone', formattedPhone); }; return ( <Field name="phone" type="text" onBlur={handleBlur} placeholder="请输入手机号" /> ); }; // 父组件使用 const PhoneForm = () => { return ( <Form> <CustomPhoneInput /> <button type="submit">提交</button> </Form> ); };
注意事项
- 不要在
onChange事件里格式化:会导致用户输入时光标跳来跳去,严重影响体验,onBlur是最合适的时机。 - 提交表单时要处理格式化后的字符串:如果后端需要纯数字手机号,记得用
replace(/\s/g, '')去掉空格。 - 格式化函数要兼容不完整输入:比如用户只输入了前3位,不要强制加空格,返回纯数字即可。
内容的提问来源于stack exchange,提问作者henkimon
相关产品推荐
相关产品推荐

