React函数组件无法使用setState?如何用useState正确更新状态?
核心问题梳理
- React 函数式组件没有类组件的
this.setState方法,你通过useState声明的状态,只能用对应返回的更新函数(也就是你代码里的setSum1、setSum2)修改。 - 你当前的更新函数调用方式错误:
useState返回的更新函数直接传入新状态值即可,不需要包裹成对象。你写的setSum1({sum1:parseFloat(sum1)})会把原本为数值类型的sum1改成对象,后续计算必然异常。 - 不能直接给状态变量赋值:你代码里的
sum1 = document.getElementById("result").value.slice(0, -1)是直接修改状态变量,React不会响应这个变更,所有状态修改必须走对应的更新函数。 - 不要直接操作DOM修改输入框内容,React推荐用受控组件模式,把输入框的值绑定到状态,通过修改状态更新视图。
修正后可运行代码
import './App.css'; import React, { useState } from 'react'; function App() { // 存储第一个运算数 const [num1, setNum1] = useState(0); // 存储运算符 const [operator, setOperator] = useState(''); // 存储输入框显示内容 const [inputValue, setInputValue] = useState(''); // 存储计算结果 const [result, setResult] = useState(0); function handleClick(e) { const buttonVal = e.target.value; // 数字按钮逻辑 if (!isNaN(buttonVal) || buttonVal === '.') { // 开头不要多余的0 if (inputValue === '' && buttonVal === '0') return; setInputValue(prev => prev + buttonVal); return; } // 清空按钮 if (buttonVal === 'clear') { setInputValue(''); setNum1(0); setOperator(''); setResult(0); return; } // 删除按钮 if (buttonVal === 'Del') { setInputValue(prev => prev.slice(0, -1)); return; } // 运算符按钮 if (['+', '-', '*', '/', '%', '^'].includes(buttonVal)) { if (!inputValue) return; // 保存第一个运算数和运算符 setNum1(parseFloat(inputValue)); setOperator(buttonVal); // 清空输入框 setInputValue(''); return; } // 等于按钮 if (buttonVal === '=') { if (!inputValue || !operator || !num1) return; const num2 = parseFloat(inputValue); let calcResult = 0; switch(operator) { case '+': calcResult = num1 + num2; break; case '-': calcResult = num1 - num2; break; case '*': calcResult = num1 * num2; break; case '/': calcResult = num1 / num2; break; case '%': calcResult = num1 % num2; break; case '^': calcResult = Math.pow(num1, num2); break; default: break; } setResult(calcResult); setInputValue(String(calcResult)); setNum1(0); setOperator(''); return; } } return ( <div className="App"> <div id="ans" className="answer">Ans = {result}</div> <input type="text" value={inputValue} readOnly placeholder="0" className="inputid" id="result" /> <hr/> <button className="opbut" value="+" onClick={handleClick}>+</button> <button className="opbut" value="-" onClick={handleClick}>-</button> <button className="opbut" value="*" onClick={handleClick}>×</button> <button className="opbut" value="/" onClick={handleClick}>÷</button> <button className="calbut" value={0} onClick={handleClick}>0</button> <button className="calbut" value={1} onClick={handleClick}>1</button> <button className="calbut" value={2} onClick={handleClick}>2</button> <button className="calbut" value={3} onClick={handleClick}>3</button> <button className="calbut" value={4} onClick={handleClick}>4</button> <button className="calbut" value={5} onClick={handleClick}>5</button> <button className="calbut" value={6} onClick={handleClick}>6</button> <button className="calbut" value={7} onClick={handleClick}>7</button> <button className="calbut" value={8} onClick={handleClick}>8</button> <button className="calbut" value={9} onClick={handleClick}>9</button> <button className="opbut" value="clear" onClick={handleClick}>C</button> <button className="opbut" value="Del" onClick={handleClick}>Del</button> <button className="opbut" value="%" onClick={handleClick}>%</button> <button className="opbut" value="^" onClick={handleClick}>y^</button> <button className="ansbut" value="=" onClick={handleClick}>=</button> <hr/> <div className="appName">A Simple React Calculator - Jayflo</div> </div> ); } export default App;
主要修改点
- 新增
inputValue状态绑定输入框的值,完全替代直接操作DOM的逻辑 - 新增
operator状态存储选中的运算符,支持多种运算逻辑 - 修正了状态更新函数的调用方式,所有状态修改都走对应的
setXXX方法 - 补充了删除、百分比、幂运算等原有按钮的对应逻辑
- 优化了输入校验,避免开头多余0、空值运算等异常情况
内容的提问来源于stack exchange,提问作者Mira BeeCalifonia
相关产品推荐
相关产品推荐

