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

React开发问题:账单输入框无法输小数、人数输入框值异常如何修复

小费计算器问题修复方案

问题1:Bill输入框无法输入小数

原因

Bill的状态被设为数字类型,作为受控组件的输入框绑定数字值后,输入小数点会被自动格式化丢失;同时handleBillChange函数中,当输入处于中间状态(如单独输入".")时,Number(".")返回NaN,导致状态不更新,无法完成小数输入。

修复步骤

  1. 将calc状态中bill的初始值改为字符串"0";
  2. 修改handleBillChange函数,保留输入的字符串格式,用正则验证是否为有效数字(允许小数、空值或单个小数点),计算时再转为Number类型。

问题2:People输入框输入数值与初始值1拼接

原因

People的状态为数字类型,输入框默认显示数字1,用户输入时输入框会将原有数字转为字符串与新输入字符拼接(如输入2时变成"12"),处理函数直接将拼接后的字符串转为数字设置回状态,导致数值错误。

修复步骤

  1. 将calc状态中people的初始值改为字符串"1";
  2. 修改handlePeoplelChange函数,用正则验证输入是否为正整数,确保输入正确覆盖原有值而非拼接。

修改后的完整代码

import "./styles.css";
import { useState } from 'react'

export default function App() {
  const [calc, setCalc] = useState({
    bill: "0", // 改为字符串初始值
    tip: 0,
    people: "1", // 改为字符串初始值
  })
  const [error, setError] = useState({
    people: false,
    bill: false
  })

  // 计算时将字符串转为Number,空值或无效值设为默认值
  const billNum = Number(calc.bill) || 0;
  const peopleNum = Number(calc.people) || 1;
  const tipPerPerson = (billNum * (calc.tip/100));
  const totalPerPerson = (billNum + tipPerPerson)/peopleNum;

  const handleBillChange = (event) => {
    const input = event.target.value;
    // 允许空值、单个小数点、整数或小数
    const validRegex = /^(\d*\.?\d*)$/;
    if (validRegex.test(input)) {
      setCalc({
        ...calc,
        bill: input || "0" // 空值时设为"0"
      });
    }
  };

  const handleTipClick = (event) => {
    const input = Number(event.target.value);
    if (!isNaN(input)) {
      setCalc({
        ...calc,
        tip: input
      });
    }
  };

  const handlePeoplelChange = (event) => {
    const input = event.target.value;
    // 仅允许正整数输入
    const validRegex = /^[1-9]\d*$/;
    if (validRegex.test(input)) {
      setError({
        ...error,
        people: false
      });
      setCalc({
        ...calc,
        people: input
      });
    } else {
      setError({
        ...error,
        people: true
      });
    }
  };

  const handleResetClick = () =>{
    setCalc({
      ...calc,
      bill: "0", // 重置为字符串"0"
      people: "1", // 重置为字符串"1"
      tip: 0
    })
  }

  return (
    <div className="App">
      <div className="calculator">
        <div className="calculator__item">
          <label htmlFor="bill" >Bill: </label>
          <input onChange={handleBillChange} placeholder="$0" value={calc.bill} id="bill"  />
        </div>
        <div className="calculator__item tip__buttons">
          <button value={10} onClick={handleTipClick}>10%</button>
          <button value={15} onClick={handleTipClick}>15%</button>
          <button value={20} onClick={handleTipClick}>20%</button>
        </div>
        <div className="calculator__item">
          <label htmlFor="people">Number of People: </label>
          <input onChange={handlePeoplelChange} placeholder="1" value={calc.people} id="people"  />
          {error.people && <p className="invalid">Must be a positive integer</p>}
        </div>
      </div>
      <div className="display">
        <p>
          Tip Amount Per Person: {(tipPerPerson).toFixed(2)}
        </p>
        <p>Total Amount Per Person: {(totalPerPerson).toFixed(2)}</p>
        <button onClick={handleResetClick}>Reset</button>
      </div>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:35:17