React欧元货币格式化组件输入值获取异常问题咨询
问题根因
欧元(it-IT 区域格式)的千位分隔符是.,小数点是,,你的代码存在两个核心逻辑错误:
- 输入转换逻辑完全错位:拿到欧元输入框的格式化值后,没有先删除千位分隔用的
.,反而把代表小数位的,误转为.,导致存入state的数值完全不符合预期 - 格式化方法入参类型错误:
Intl.NumberFormat接收数值类型才能正常执行规则,你直接传入字符串会导致解析逻辑混乱,出现格式化结果和输入不匹配的问题
修复后代码
import "./styles.css"; import { useState } from "react"; export default function App() { const [inputValue, setInputValue] = useState(""); const [inputUsdValue, setinputUsdValue] = useState(""); const currencyFunction = (formatData) => { // 空输入直接返回空,避免格式化出0占位 if (!formatData) return ""; // 先转成数字再格式化 return new Intl.NumberFormat('it-IT', { // 可选:如果需要固定保留2位小数可以打开下面的配置 // minimumFractionDigits: 2, // maximumFractionDigits: 2 }).format(Number(formatData)) } const currencyFunctionDolar = (formatData) => { if (!formatData) return ""; return new Intl.NumberFormat('en-US').format(Number(formatData)) } return ( <div className="App" style={{ display: "flex", flexFlow: "column" }}> <h1>Test component</h1> <p>Euro format</p> <p>Euro format example {currencyFunction(123456789)}</p> <input value={currencyFunction(inputValue)} onChange={e => { let val = e.target.value // 第一步:删除千位分隔符. val = val.replace(/\./g, '') // 第二步:把欧元格式的小数位,转成标准数值用的. val = val.replace(/,/g, '.') // 第三步:过滤非数字和小数点的字符 val = val.replace(/[^0-9.]/g, '') // 第四步:处理多个小数点的异常输入 const dotCount = (val.match(/\./g) || []).length if (dotCount > 1) { const firstDotIndex = val.indexOf('.') val = val.slice(0, firstDotIndex + 1) + val.slice(firstDotIndex + 1).replace(/\./g, '') } // 可选:处理多余前导0 val = val.replace(/^0+(?=\d)/, '') setInputValue(val) }} style={{ marginBottom: 20 }} /> <p>Usd format</p> <p>Usd format example {currencyFunctionDolar(123456789)}</p> <input value={currencyFunctionDolar(inputUsdValue)} onChange={e => { setinputUsdValue(e.target.value.replace(/,/g, '').replace(/([a-zA-Z ])/g, "").replace(/^0+/, '')) }} /> </div> ); }
补充说明
如果需要支持小数输入,建议在Intl.NumberFormat的配置项里添加minimumFractionDigits和maximumFractionDigits限制小数位数,避免输入小数时出现格式跳动问题。
内容的提问来源于stack exchange,提问作者Evren
相关产品推荐
相关产品推荐

