需要输出说明。需要了解钩子的顺序并重新渲染工作

时间:2019-05-23 16:59:30

标签: javascript reactjs react-hooks

在调用set(state)时,我无法理解效果和重新渲染工作的顺序。我知道默认情况下,每个渲染效果都会保证运行。但是在这种情况下,无法应用相同的原理来匹配生成的输出。

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>
  );
}

输出

  1. <===渲染===>
  2. 跑步效果
  3. 设置前标志为假
  4. <===渲染===>
  5. 设置后标志为假
  6. 设置计数为0之前
  7. 跑步效果
  8. <===渲染===>
  9. 设置后计数为0
  10. 设置之前标志为真
  11. 跑步效果
  12. <===渲染===>
  13. AFTER SET标志为真
  14. 设置计数为0之前
  15. 设置后计数为0
  16. 设置之前标志为真
  17. AFTER SET标志为真
  18. 设置前计数20
  19. 设置后计数20

1 个答案:

答案 0 :(得分:0)

好,这是正在发生的事情: Promise.resolve().then基本上是在效果阶段之后将then块的执行排队,这就是为什么在这种情况下setState立即触发一个新的渲染,然后在下一个效果开始执行之前然后该块继续。

我对您的代码进行了一些修改,以帮助您更好地理解每个渲染器属于什么console.log。

https://codesandbox.io/s/weathered-lake-heh9j

开始渲染

#1 "<===rendering===>" false 0

第一个渲染结束渲染

第一个渲染效果开始

#1 "Running Effects" false 0

第一个渲染效果结束

首先渲染Promise。然后开始块

#1 "BEFORE SET flag" false 0

第一个渲染setCount立即调用下一个渲染,因为我们已经完成了效果阶段 第二次渲染开始

#2 "<===rendering===>" true 0

第二个渲染结束渲染

首先渲染Promise。然后继续执行块

#1 "AFTER SET flag" false 0
#1 "BEFORE SET count" false 0

第一个渲染setCount立即调用第三个渲染,因为我们已经完成了效果阶段,但是在渲染做出反应之前,第二个渲染待处理效果

第二个渲染效果开始

#2 "Running Effects" true 0

第二个渲染效果结束

第三个渲染开始

#3 "<===rendering===>" true 20

第三个渲染结束渲染

首先渲染Promise。然后继续执行块

#1 "AFTER SET count" false 0

首先渲染Promise。然后结束块=>首先完成所有渲染

第二次渲染Promise。然后开始块

#2 "BEFORE SET flag" true 0

第二个渲染setCount立即调用第四个渲染,因为我们已经完成了效果阶段,但是在渲染之前,第三个渲染待处理效果会做出反应

第三个渲染效果开始

#3 "Running Effects" true 20

第三种渲染效果结束

第四个渲染开始

#4 "<===rendering===>" true 20

第四个渲染结束,因为计数和标志未更改

,因此没有效果

第二次渲染Promise。然后继续执行块

#2 "AFTER SET flag" true 0
#2 "BEFORE SET count" true 0
#2 "AFTER SET count" true 0

第二次渲染Promise。然后块结束

第三个渲染Promise。然后块开始

#3 "BEFORE SET flag" true 20
#3 "AFTER SET flag" true 20
#3 "BEFORE SET count" true 20
#3 "AFTER SET count" true 20

第三个渲染Promise。然后块结束

以下修改后的示例可能会进一步帮助您了解反应的作用。

https://codesandbox.io/s/competent-wozniak-syr0s

请注意,当您单击设置标志为true的按钮时,不会触发任何渲染,因为react会比较新状态和以前的状态,并且可能决定不进行渲染。