使用Formik处理SSN格式化时,单次删除需双击的问题求助
SSN输入框删除字符需双击的问题修复
问题根源
- 状态不一致:同时使用Formik表单状态和自定义
useState管理SSN值,导致TextField绑定的Formik值与normalizeInput依赖的ssn状态不同步。 - 删除逻辑缺失:
normalizeInput仅处理输入字符(值长度增加)的场景,删除字符时无对应格式化逻辑,函数无返回值导致单次删除后状态更新异常。
修正方案
1. 统一用Formik管理状态
移除自定义useState,Formik本身具备表单状态管理能力,可避免状态同步问题。
2. 完善格式化函数逻辑
无论输入还是删除操作,都基于纯数字长度返回对应格式化字符串,确保所有场景下函数都有正确返回值。
修正后的完整代码
const normalizeInput = (value: any) => { // 空值直接返回 if (!value) return value; // 过滤所有非数字字符 const currentValue = value.replace(/[^\d]/g, ''); const cvLength = currentValue.length; // 根据数字长度返回对应格式 if (cvLength < 4) return currentValue; if (cvLength < 7) return `${currentValue.slice(0, 3)}-${currentValue.slice(3)}`; return `${currentValue.slice(0, 3)}-${currentValue.slice(3, 5)}-${currentValue.slice(5, 9)}`; };
<form onSubmit={formik.handleSubmit}> <TextField name="ssn" id="ssn" label="SSN*" variant="filled" value={formik.values.ssn} onChange={(e) => { // 用Formik的setFieldValue更新表单状态 formik.setFieldValue('ssn', normalizeInput(e.target.value)); }} /> </form>
补充说明
- 移除原函数对
previousValue的依赖,直接基于当前输入的纯数字长度处理格式,简化分支判断逻辑。 - 用
formik.setFieldValue替代自定义setSsn,确保表单状态完全由Formik管理,彻底消除状态不一致问题。
内容的提问来源于stack exchange,提问作者Florence Adikwu
相关产品推荐
相关产品推荐

