一步延迟更新导致 React State
Posted
技术标签:
【中文标题】一步延迟更新导致 React State【英文标题】:One step delay in updating result in React State 【发布时间】:2020-08-25 22:00:44 【问题描述】:我有一个非常简单的计算器,它通过 React 计算两个输入,我在更新我的 state 中的 result
时遇到问题(将 result
状态更新为函数称为calc
)。这是通过下一个动作完成的,而不是现在!
总而言之,现在结果状态计算出错误的值。
我的代码:
const App = () =>
const [state, setState] = useState(
firstVal: 0,
secondVal: 0,
operator: "+",
result: 0
);
const firstVal, secondVal, operator, result = state;
const calc = (firstVal, secondVal, operator) =>
if (operator === "+")
return firstVal + secondVal;
else if (operator === "-")
return firstVal - secondVal;
else if (operator === "*")
return firstVal * secondVal;
else if (operator === "/")
return firstVal / secondVal;
;
const changeHandler = e =>
setState(
...state,
[e.target.name]:
e.target.name === "operator" ? e.target.value : Number(e.target.value),
result: calc(firstVal, secondVal, operator)
);
;
return (
<div className="App">
<input name="firstVal" onInput=changeHandler />
<select name="operator" onChange=changeHandler>
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input name="secondVal" onInput=changeHandler />
<p>result</p>
</div>
);
;
export default App;
我想我不了解 React 中的异步和状态。
这是我在codesandbox中的代码
【问题讨论】:
您能准确指出您的问题是什么吗?从您的描述中现在还不清楚。 您误解了状态的工作原理,看起来您正在尝试使用单个changeHandler
函数来执行大约 4 个不同的任务。您根本不应该将结果存储在 state 中,因为结果是使用已经处于 state 中的值计算的。
我希望我的结果显示一个正确的值。 @TomOakley
你说你对状态一无所知。你可以read about state here,它会解释你哪里出错了。
@JMadelaine tnx,您的意思是每个处理程序都需要一个特定且单独的状态?
【参考方案1】:
不要将result
保存在您的状态中,只需在渲染时使用calc
方法计算结果即可。
return (
<div className="App">
<input name="firstVal" onInput=changeHandler />
<select name="operator" onChange=changeHandler>
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input name="secondVal" onInput=changeHandler />
<p>calc(firstVal, secondVal, operator)</p>
</div>
);
我也不会使用状态对象 - 为每个状态变量使用不同的状态值和方法,例如:
import React, useState from "react";
import "./styles.css";
const App = () =>
const [firstVal, setFirstVal] = useState(0)
const [secondVal, setSecondVal] = useState(0)
const [operator, setOperator] = useState('+')
const calc = (firstVal, secondVal, operator) =>
if (operator === "+")
return firstVal + secondVal;
else if (operator === "-")
return firstVal - secondVal;
else if (operator === "*")
return firstVal * secondVal;
else if (operator === "/")
return firstVal / secondVal;
;
return (
<div className="App">
<input name="firstVal" onInput=e => setFirstVal(Number(e.target.value)) />
<select name="operator" onChange=e => setOperator(e.target.value)>
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input name="secondVal" onInput=e => setSecondVal(Number(e.target.value)) />
<p>calc(firstVal, secondVal, operator)</p>
</div>
);
;
export default App;
这消除了changeHandler
方法的复杂混乱,并使代码更具可读性。
【讨论】:
【参考方案2】:问题出在:
const changeHandler = e =>
setState(
...state,
[e.target.name]:
e.target.name === "operator" ? e.target.value : Number(e.target.value),
result: calc(firstVal, secondVal, operator)
);
;
当calc
被调用时,它仍然具有来自当前 状态的值,而不是通过onChange
/onInput
处理程序设置的新值,因此观察到陈旧结果。
编辑:此答案试图解释观察到的行为发生的原因。至于如何解决,请看汤姆的回答。
【讨论】:
谢谢,我的解决方案是结合您的回答和汤姆的回答。以上是关于一步延迟更新导致 React State的主要内容,如果未能解决你的问题,请参考以下文章