我收到的两个不同的console.log打印订单,基于我是否使用了诺言。
状态:
let [data,setData] = useState(1);
使用诺言时:
let asyncFunk = async () => {
return "Asd";
};
useEffect(() => {
asyncFunk().then((result) => {
console.log("BEFOR SET DATA " +data);
setData(prev => prev +1 );
console.log("AFTER SET DATA " +data);
});
},[]);
return (
<div>
{console.log("Data in return " + data)}
</div>
);
}
console.log的打印顺序为:
Data in return 1
BEFOR SET DATA 1
Data in return 2
AFTER SET DATA 1
因此,当点击setData()时,组件将重新渲染,并且从setData()之后在console.log之前将返回的console.log命名为
。当我删除异步功能时:
useEffect(() => {
console.log("BEFOR SET DATA " +data);
setData(prev => prev +1 );
console.log("AFTER SET DATA " +data);
},[]);
return (
<div>
{console.log("Data in return " + data)}
</div>
);
}
console.log的打印顺序为:
Data in return 1
BEFOR SET DATA 1
AFTER SET DATA 1
Data in return 2
删除异步功能后,useEffect首先完成,并且还打印旧状态值,然后打印返回的console.log。
您知道这里发生了什么以及为什么打印顺序是这样吗?
答案 0 :(得分:1)
这是React的实现。
请查看this answer上的字样。
TL; DR –如果状态更改是异步触发的(例如,包装在Promise中),则不会进行批量处理;如果直接触发它们,将对其进行批处理。
如果您查看comment of Dan Abramov,它会显示
在当前版本中,如果您位于React事件处理程序中,则会将它们一起批处理。
...
在当前版本中,事件处理程序外部(例如,网络响应中)的几个setState将不会被批处理。因此,在这种情况下,您将获得两次重新赠送。 ...
那么在什么地方发生了预期的结果。