为什么useState会导致多次渲染

时间:2020-07-16 04:34:46

标签: reactjs

我正在调查useState为何导致渲染如此多的时间,例如以下应用或here

import React from "react";

export default function App() {
  const [name, setName] = React.useState("unknown");
  console.log("render...", name);
  React.useEffect(() => {
    const doIt = async () => {
      await new Promise(res => setTimeout(res, 1000));
      setName("Ron");
    };
    doIt();
  }, []);
  return <div className="App">{name}</div>;
}

我认为它应该渲染2次,其中1个用于初始,再加上useEffect。但是为什么它实际渲染4次如下?

render... unknown 
render... unknown 
render... Ron 
render... Ron 

2 个答案:

答案 0 :(得分:2)

console语句位于函数主体中,React将在每个渲染器上执行函数主体。

  1. 在组件安装时,由于init状态为空,因此控制台将打印一个空字符串。
  2. 在更新组件Mount上的状态时,React将再次执行功能主体,然后使用更新后的值记录状态。

在使用React.StrictMode时,它可以多次渲染组件。这就是您多次看到控制台日志的原因。

提交阶段通常非常快,但是渲染可能很慢。因此,即将到来的并发模式(默认情况下尚未启用)将渲染工作分解为多个部分,暂停并恢复工作以避免阻塞浏览器。这意味着React可以在提交之前多次调用渲染阶段生命周期,也可以根本不提交而调用它们(由于错误或更高优先级的中断)。 渲染阶段生命周期包括以下类组件方法:

  1. 构造函数
  2. componentWillMount(或UNSAFE_componentWillMount)
  3. componentWillReceiveProps(或UNSAFE_componentWillReceiveProps)
  4. componentWillUpdate(或UNSAFE_componentWillUpdate)
  5. getDerivedStateFromProps
  6. shouldComponentUpdate渲染
  7. setState更新程序功能(第一个参数)

由于上述方法可能会被多次调用,因此请不要包含任何副作用,这一点很重要。忽略此规则可能导致各种问题,包括内存泄漏和无效的应用程序状态。不幸的是,由于这些问题通常是不确定的,因此很难检测到它们。

您可以了解有关React.StrictMode here

的更多信息

答案 1 :(得分:0)

这是因为您正在setState中进行useEffect,而没有任何依赖性。因此,无论何时渲染组件,使用效果都将像componentDidMount一样工作,然后在其中,有setState会引起另一次渲染,并再次调用componentDidmount。它有点使整个过程循环。