React text类型输入框格式化数字失焦后出现NaN问题求助
问题原因
失焦后返回NaN的核心原因是第一次格式化完成后,输入框值里包含千位分隔符逗号,当你再次编辑触发失焦时,代码直接拿带逗号的字符串(比如12,345.67)执行Number()转换,JS无法识别带逗号的数字字符串,会直接返回NaN。
另外你的三元判断逻辑存在漏洞:NaN.toFixed(2)会返回字符串"NaN",这个值是truthy类型,判断条件会直接走逗号替换分支,根本不会触发你写的0.00兜底逻辑,最终就把NaN写回了输入框。
其他隐藏问题:
- onKeyPress事件只能拦截键盘输入的非法字符,无法拦截右键粘贴、拖拽填入的异常内容
- 没有对格式化生成的逗号做预处理,每次失焦转换都直接读取带格式的字符串做数值运算
修复代码
直接替换原有的onBlur逻辑即可:
onBlur={event => { // 先移除当前值里所有已存在的千分位逗号,拿到纯数字字符串 const rawVal = props.values['initialBalance']?.replace(/,/g, '').trim() || ''; const numVal = Number(rawVal); // 无效数值直接兜底为0.00 const decimalStr = isNaN(numVal) ? (0).toFixed(2) : numVal.toFixed(2); // 插入千分位逗号后写回 const formattedVal = decimalStr.replace(/\B(?=(\d{3})+(?!\d))/g, ','); props.setFieldValue('initialBalance', formattedVal); props.handleBlur(event); }}
可选优化
- 可以在onChange回调里提前把输入内容里的逗号移除,避免中间状态存带格式的字符串,降低转换异常概率
- 如果后续需要用这个字段做数值计算,记得先把值里的逗号全部替换掉再转数字,不要直接用格式化后的带逗号值参与运算
- 建议把输入合法性校验从onKeyPress移到onChange里,覆盖粘贴、拖拽等非键盘输入场景,避免非法值存入
内容的提问来源于stack exchange,提问作者Hanakoizumi
相关产品推荐
相关产品推荐

