如何解决在哪些情况下可以在没有回调的情况下更新状态导致问题?
考虑以下代码:
import React,{ useState } from "react";
function App() {
const [counter,setCounter] = useState(0);
function handleClick() {
setCounter(counter + 1); // update counter without using a callback
}
return (
<div>
<button type="button" onClick={() => handleClick()}>
increase counter
</button>
<div>counter is {counter}</div>
</div>
);
}
export default App;
我是 React 的新手,听说如果一个状态应该基于它之前的值,我必须使用回调来更新状态。出于学习目的,我故意做了相反的事情:在不使用回调的情况下更新状态。我尽可能快地多次单击“增加计数器”按钮,但没有注意到任何问题。好像算对了。所以:
- 我的示例代码是否会导致点击次数不计算在内,例如我点击按钮 10 次,但
counter
最终只有 9 次? - 这究竟是如何以及为什么会发生的?
解决方法
考虑它的最好方法是您是否希望它围绕变量的当前值进行闭包。例如,玩这个:
function handleClick() {
setCounter(counter + 1);
setCounter(counter + 1);
}
您可能期望它是 2
,但它是 1
!这是因为两个调用都是setCounter(0 + 1)
。但是,如果您这样做了:
function handleClick() {
setCounter(c => c + 1);
setCounter(c => c + 1);
}
你确实得到了 2
。这是因为当每个 setCounter
函数运行时,它都会调用当前状态的回调(而不是它关闭的值)。
这是一个非常简单的例子,但现在考虑执行几个异步获取调用,如果不使用回调,可能会用另一个调用的状态覆盖一个调用!
const [data,setData] = useState({})
useEffect(() => {
fetch("http://example.resource")
.then(res => res.json())
.then(res => {
setData({...data,res})
});
fetch("http://another.example.resource")
.then(res => res.json())
.then(res => {
setData({...data,res})
});
},[]);
在本例中,无论哪个 fetch
第二次返回都会破坏第一次返回的数据,因为它将使用过时的 data
引用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。