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

React计算器无法输入多位数问题求助

问题分析与修复方案

你的核心问题有两个:

  • 用普通数组numbers存储输入的数字片段,而非React状态变量,导致数组更新后组件不会重新渲染,无法追踪最新的输入序列
  • 组件每次渲染都会重置numbers为空数组,加上setButton函数逻辑错误,根本无法累积数字

具体修复步骤:

  1. 将numbers改为React状态
    用useState声明numbers,这样数组变化时会触发组件重渲染,能正确追踪输入的数字序列:

    const [numbers, setNumbers] = useState([]);
    
  2. 重写setButton函数
    修改逻辑,实现未输入运算符时拼接数字的功能:

    function setButton(event) {
      const inputNum = event.target.name;
      // 无运算符时累积数字,有运算符时重置为当前输入的数字
      if (symbol === "") {
        setNumbers(prev => [...prev, inputNum]);
        setNum(prev => (prev === 0 ? inputNum : prev + inputNum));
      } else {
        setNumbers([inputNum]);
        setNum(inputNum);
        setSymbol("");
      }
    }
    
  3. 修复ac函数的重置逻辑
    不能直接给numbers赋值,必须用状态更新函数重置:

    function ac() {
      setNum(0);
      setSymbol("");
      setNumbers([]);
    }
    
  4. 优化symbolF函数的即时计算
    原逻辑中setSymbol是异步操作,需改用当前点击的运算符,避免状态延迟问题:

    function symbolF(event) {
      const currentSymbol = event.target.name;
      let number = 0;
    
      if (prevCount === 0) {
        setSymbol(currentSymbol);
        return;
      }
    
      if (!symbol) {
        setSymbol(currentSymbol);
        return;
      }
    
      switch (symbol) {
        case "+":
          number = add(Number(prevCount), Number(num));
          break;
        case "-":
          number = subtract(Number(prevCount), Number(num));
          break;
        case "*":
          number = multiply(Number(prevCount), Number(num));
          break;
        case "/":
          number = divide(Number(prevCount), Number(num));
          break;
      }
    
      setNum(number);
      setSymbol(currentSymbol);
      setNumbers([]);
    }
    

完整修复后的App.js代码:

import React, { useState, useEffect, useRef } from "react";
import { add, subtract, multiply, divide } from "../functions.js";
import "../styles.css";

function App() {
  const [num, setNum] = useState(0);
  const [symbol, setSymbol] = useState("");
  const [numbers, setNumbers] = useState([]);
  const symbols = ["+", "-", "*", "/"];

  function setButton(event) {
    const inputNum = event.target.name;
    if (symbol === "") {
      setNumbers(prev => [...prev, inputNum]);
      setNum(prev => (prev === 0 ? inputNum : prev + inputNum));
    } else {
      setNumbers([inputNum]);
      setNum(inputNum);
      setSymbol("");
    }
  }

  function usePrevious(value) {
    const ref = useRef();
    useEffect(() => {
      ref.current = value;
    }, [value]);
    return ref.current;
  }

  const prevCount = usePrevious(num);

  function EqualTo() {
    let number = 0;
    switch (symbol) {
      case "+":
        number = add(Number(prevCount), Number(num));
        break;
      case "-":
        number = subtract(Number(prevCount), Number(num));
        break;
      case "*":
        number = multiply(Number(prevCount), Number(num));
        break;
      case "/":
        number = divide(Number(prevCount), Number(num));
        break;
    }
    setNum(number);
    setSymbol("");
    setNumbers([]);
  }

  function ac() {
    setNum(0);
    setSymbol("");
    setNumbers([]);
  }

  function symbolF(event) {
    const currentSymbol = event.target.name;
    let number = 0;

    if (prevCount === 0) {
      setSymbol(currentSymbol);
      return;
    }

    if (!symbol) {
      setSymbol(currentSymbol);
      return;
    }

    switch (symbol) {
      case "+":
        number = add(Number(prevCount), Number(num));
        break;
      case "-":
        number = subtract(Number(prevCount), Number(num));
        break;
      case "*":
        number = multiply(Number(prevCount), Number(num));
        break;
      case "/":
        number = divide(Number(prevCount), Number(num));
        break;
    }

    setNum(number);
    setSymbol(currentSymbol);
    setNumbers([]);
  }

  function forInpute(event) {
    setNum(event.target.value);
    setNumbers(event.target.value.split(""));
  }

  return (
    <div>
      <br />
      <input type="number" placeholder="Enter num" value={num} onChange={forInpute}></input>
      <br />
      <button onClick={setButton} name="1">1</button>
      <span><button name="2" onClick={setButton}>2</button></span>
      <span><button name="3" onClick={setButton}>3</button></span>
      <span><button name="+" onClick={symbolF}>+</button></span>
      <br />
      <button name="4" onClick={setButton}>4</button>
      <span><button name="5" onClick={setButton}>5</button></span>
      <span><button name="6" onClick={setButton}>6</button></span>
      <span><button name="-" onClick={symbolF}>-</button></span>
      <br />
      <button name="7" onClick={setButton}>7</button>
      <span><button name="8" onClick={setButton}>8</button></span>
      <span><button name="9" onClick={setButton}>9</button></span>
      <span><button name="*" onClick={symbolF}>*</button></span>
      <br />
      <span><button name="0" onClick={setButton}>0</button></span>
      <span><button name="." onClick={setButton}>.</button></span>
      <span><button name="/" onClick={symbolF}>/</button></span>
      <br />
      <button onClick={EqualTo}>=</button>
      <br />
      <button onClick={ac}>AC</button>
    </div>
  );
}

export default App;

关键说明:

  • 用useState管理numbers数组,确保输入变化时组件能正确更新
  • setButton通过判断symbol是否为空,决定拼接数字或重置输入
  • 修复了状态更新的异步问题,避免逻辑错误
  • 同步了输入框手动输入与按钮输入的状态一致性

内容的提问来源于stack exchange,提问作者Farhad Hassan A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 08:10:29