我无法理解效果&在调用设置(状态(时,请渲染工作。我知道,默认情况下,保证每种渲染效果可以运行。但是在这种情况下,无法应用相同的原理与生成的输出匹配。
function Example() {
const [count, setCount] = useState(0);
const [flag, setFlag] = useState(false);
console.log("<===rendering===>");
useEffect(() => {
console.log("Running Effects")
Promise.resolve(1)
.then(() => {
console.log("BEFORE SET flag", flag);
setFlag(true);
console.log("AFTER SET flag", flag);
console.log("flag4 SET count", count);
setCount(20);
console.log("AFTER SET count", count);
})
}, [flag, count]);
return (
<div>
Hello
</div>
);
}
输出
- &lt; ===渲染===>
- 运行效果
- 设置标志false false
- &lt; ===渲染===>
- 设置标志false false
- 设置计数之前0
- 运行效果
- &lt; ===渲染===>
- 设置计数后0
- 在设置标志true之前
- 运行效果
- &lt; ===渲染===>
- 设置标志true
- 设置计数之前0
- 设置计数后0
- 在设置标志true之前
- 设置标志true
- 设置计数之前20
- 设置计数20
好吧,这就是发生的事情:Promise.resolve().then
基本上是将当时的块的执行排队为效果阶段之后,这就是为什么在这种情况下,setState
s立即触发新的渲染,然后,在下一个效果开始执行之前,当时的块继续执行。
我对您进行了一些修改,以帮助更好地了解console.log属于每个渲染。
https://codesandbox.io/s/weathered-lake-heh9j
首次渲染开始
#1 "<===rendering===>" false 0
第一个渲染端渲染
第一个渲染效果开始
#1 "Running Effects" false 0
第一个渲染效果结束
第一个渲染诺言。 首先渲染setCount立即调用下一个渲染,因为我们已经完成了效果阶段第二播放开始 第二渲染末端渲染 第一个渲染诺言。 第一个渲染setCount立即调用第三渲染,因为我们已经完成了效果阶段,但是在渲染react进行第二次渲染效果之前, 第二个渲染效果开始 第二渲染效果结束 第三渲染启动 第三渲染末端渲染 第一个渲染诺言。 第一个渲染Promise.Then Block End =>首先渲染全部完成 第二个渲染诺言。 第二渲染setCount立即调用第四渲染,因为我们已经完成了效果阶段,但是在渲染之前,React会执行第三次渲染效果 第三渲染效果开始 第三渲染效果结束 第四渲染启动 第四渲染结束,没有效果,因为计数和标志没有更改 第二个渲染诺言。 第二个渲染Promise.Then Block End 第三渲染诺言。 第三渲染诺言。 以下修改后的示例可能会进一步帮助理解反应的作用。 https://codesandbox.io/s/competent-wozniak-syr0s 请注意,当您单击"设置标志" true按钮时,没有触发渲染。#1 "BEFORE SET flag" false 0
#2 "<===rendering===>" true 0
#1 "AFTER SET flag" false 0
#1 "BEFORE SET count" false 0
#2 "Running Effects" true 0
#3 "<===rendering===>" true 20
#1 "AFTER SET count" false 0
#2 "BEFORE SET flag" true 0
#3 "Running Effects" true 20
#4 "<===rendering===>" true 20
#2 "AFTER SET flag" true 0
#2 "BEFORE SET count" true 0
#2 "AFTER SET count" true 0
#3 "BEFORE SET flag" true 20
#3 "AFTER SET flag" true 20
#3 "BEFORE SET count" true 20
#3 "AFTER SET count" true 20