const [count,setCount]=useState(5)
useEffect(()=>{
setCount(10)},[count])
在上面的代码中,如果我在没有异步操作的情况下更新状态,则useEffect不会进入infite循环。而在下面的代码中,如果我通过asysnc操作更新state,它会进入infite循环,有人能告诉我在异步操作的情况下useEffect的行为吗?
const [count,setCount]=useState(5)
useEffect(()=>{
//some async operation
.then(response)=>{
setCount(response.data)}},[count])
这是因为数字通过引用与值和对象进行比较。每次异步操作都会导致新的对象引用,因此useEffect
会触发。
在像setCount(5)
这样的数字的情况下,由于第二次5
是与前一次相同的变量,因此不会再次触发。
这是个好问题!
在第一个代码段中,您将计数设置为10,该值不会动态更改,因此它将更改一次,并等待计数再次更改,而在第二个代码段,一旦异步操作完成,它将更新count
,因此useEffect
将与其中的异步操作一起再次触发。因此,它进入递归更新。
如果你愿意,你可以像这样更改第一个片段,以查看递归更新
setCount(count + 1);
这是钩子及其更新状态的方法,如果您以前的状态值和当前状态值相同,则react功能组件不会重新呈现,因此,如果您使用的是对象类型的状态,则建议始终创建新对象,或在更新状态时使用spread运算符更新对象内部的任何属性。在您的情况下,setCount(10(将始终返回一个常数值10,因此useEffect不会触发无限次,因为计数理论上从5更改为10一次,但对于API请求,它将始终返回具有新引用的对象,因此它将创建一个无限循环。您也可以在API结果中执行setCount(10(,它也不会触发useEffect,因为计数基本上从不从10更改,除非从5更改为10。