如何在TypeScript React现有货币输入组件中实现千位逗号分隔
货币输入框千位分隔集成方案
现有TypeScript React组件代码
const valueRef = React.useRef<HTMLInputElement>(null); const CurrencyInput = () => { const [focus, setFocus] = React.useState<boolean>(false); return ( <> <CurrencyContainer onClick={() => valueRef.current?.focus()} isFocused={focus} > <CurrencyInput type="number" value={storage.updatesomevalue} onChange={e => dispatch(updatesomevalue(parseInt(e.target.value)))} ref={valueRef} onFocus={() => setFocus(true)} onBlur={() => setFocus(false)} /> <Currency>USD</Currency> </CurrencyContainer> </> ); };
说明:<CurrencyContainer>是styled div,<CurrencyInput>是styled input,<Currency>是styled p
需求
实现货币输入框数字的千位逗号分隔显示,例如输入1000000时,显示为1,000,000。
集成实现方案
步骤1:新增工具函数
先定义格式化和解析数字的工具函数,用于处理千位分隔的转换:
// 把数字转为带千位分隔的字符串 const formatNumber = (num: number): string => { return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); }; // 把带千位分隔的字符串转回数字 const parseFormattedNumber = (str: string): number => { return parseInt(str.replace(/,/g, ''), 10) || 0; };
步骤2:重构组件代码
修改输入框类型并新增状态管理显示值,核心是区分「存储的原始数字」和「显示的格式化字符串」:
const CurrencyInput = () => { const [focus, setFocus] = React.useState<boolean>(false); const [displayValue, setDisplayValue] = React.useState<string>(''); const valueRef = React.useRef<HTMLInputElement>(null); // 初始化时用原始值生成格式化显示内容 React.useEffect(() => { setDisplayValue(formatNumber(storage.updatesomevalue)); }, [storage.updatesomevalue]); const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { // 过滤输入中的非数字字符 const rawInput = e.target.value.replace(/[^0-9]/g, ''); // 生成格式化后的显示内容 const formatted = rawInput ? formatNumber(parseInt(rawInput, 10)) : ''; setDisplayValue(formatted); // 解析为原始数字更新store dispatch(updatesomevalue(parseFormattedNumber(formatted))); }; const handleFocus = () => { setFocus(true); // 聚焦时显示原始数字,方便连续输入 setDisplayValue(storage.updatesomevalue.toString()); }; const handleBlur = () => { setFocus(false); // 失焦时重新转为格式化显示 setDisplayValue(formatNumber(storage.updatesomevalue)); }; return ( <> <CurrencyContainer onClick={() => valueRef.current?.focus()} isFocused={focus} > <CurrencyInput type="text" value={displayValue} onChange={handleChange} ref={valueRef} onFocus={handleFocus} onBlur={handleBlur} /> <Currency>USD</Currency> </CurrencyContainer> </> ); };
关键说明
- 把输入框类型从
number改为text:因为number类型无法渲染带逗号的格式化字符串,会自动过滤非数字字符,导致格式化失效。 - 用
displayValue状态单独管理显示内容:确保存储到storage的始终是原始数字,避免格式化后的字符串干扰数据逻辑。 - 聚焦/失焦的优化处理:聚焦时显示原始数字,减少输入时的格式干扰;失焦时恢复格式化显示,保证界面展示的规范性。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

