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

MUI TextField无法输入小数求助:自定义货币输入框异常排查

问题根源

你的代码在处理输入小数点的中间状态(比如输入123.还没输入小数部分时)会丢失小数点,导致输入框回显时覆盖用户的输入,看起来像是被阻止输入。

具体来说:当用户输入123.,Number(s.replaceAll(",",""))会把"123."转换成数字123,再通过Intl.NumberFormat格式化后得到"123",setVal后输入框的值被替换成"123",相当于删掉了用户刚输入的小数点。而粘贴完整小数(如123.45)时,转换后的数字是123.45,格式化会保留小数部分,所以功能正常;去掉value属性后,输入框不受状态控制,自然可以自由输入。

修复方案

修改handleChangeNumber函数,针对带小数点的中间状态做特殊处理,保留用户输入的小数点:

const [_val, setVal] = React.useState("");

const handleChangeNumber = (e: any) => {
  try {
    let s = e.target.value;
    const cleanStr = s.replaceAll(",", "");
    let formatedValue: string;

    // 情况1:输入内容以小数点结尾(如"123."或".")
    if (cleanStr.endsWith('.')) {
      const numPart = cleanStr.slice(0, -1);
      const num = numPart ? Number(numPart) : 0;
      // 空输入小数点时显示"0.",符合货币输入习惯
      formatedValue = numPart ? `${numberFormatWithoutCurrency(num)}.` : "0.";
    } 
    // 情况2:输入内容包含小数点且后面有数字(如"123.45")
    else if (cleanStr.includes('.')) {
      const [integerPart, decimalPart] = cleanStr.split('.');
      const num = Number(integerPart);
      const formattedInteger = numberFormatWithoutCurrency(num);
      formatedValue = `${formattedInteger}.${decimalPart}`;
    } 
    // 情况3:纯整数输入(如"1234")
    else {
      const valueInNumber = Number(cleanStr) || 0;
      formatedValue = numberFormatWithoutCurrency(valueInNumber);
    }

    setVal(formatedValue);
  } catch (error) {
    console.log(error);
  }
};
关键修改点
  • 单独处理末尾带小数点的输入,避免转换成数字时丢失小数点
  • 拆分带小数的输入,分别格式化整数部分,再拼接小数部分
  • 对空输入小数点的情况,自动补0.,符合货币输入的常规体验

内容的提问来源于stack exchange,提问作者Muhammad Hassaan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 14:40:19