You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 15:10:25