我正在阅读Reaction网站上的学习react 文档,在排队一系列状态更新部分有一句话是这样写的 在您的事件处理和其中的任何代码完成之前,不会更新UI.从这里我得到的印象是只能有一种渲染 每次onClick事件,但在运行下面的组件时,该组件似乎重新呈现了两次.一次是在添加挂起状态时,另一次是在setTimeout函数内递减挂起状态和递增状态时.

function RequestTracker() {
  const [pending, setPending] = useState(0);
  const [completed, setCompleted] = useState(0);
  useEffect(() => {
    console.log("MyComponent rendered!");
  });

  function handleClick() {
    setPending((p) => p + 1);
    setTimeout(() => {
      setCompleted((c) => c + 1);
      setPending((p) => p - 1);
    }, 3000);
  }

  return (
    <>
      <h3>Pending: {pending}</h3>
      <h3>Completed: {completed}</h3>
      <button onClick={handleClick}>Buy</button>
    </>
  );
}

这是否与仅呈现UIafter的语句相矛盾,事件处理程序完成其中的所有代码?

使用useEffect,每次单击确实有多个渲染.我应该怎么想 如何对重新渲染进行排队和执行.谢谢!

推荐答案

只有在您的事件处理和其中的任何代码完成之后,才会更新UI.

这句话是真的.在组件重新呈现之前,您的handleClick函数即将完成.

但在运行以下组件时,该组件似乎重新呈现了两次

在这种情况下,这是意料之中的.仔细看看代码在做什么:

function handleClick() {
  setPending((p) => p + 1);
  setTimeout(() => {
    setCompleted((c) => c + 1);
    setPending((p) => p - 1);
  }, 3000);
}

功能handleClick做什么?恰好有两件事:

  1. 拨打setPending对状态更新进行排队.
  2. 调用setTimeout来调度某个函数在以后的某个时间执行.

那就完了.该函数已经运行到完成,执行了它的所有任务,并且框架现在看到状态更新已经排队,并且框架重新呈现具有新状态的组件.

然后,at some later time,会发生这样的情况:

setCompleted((c) => c + 1);
setPending((p) => p - 1);

它恰好做了两件事:

  1. 拨打setCompleted对状态更新进行排队.
  2. 拨打setPending对状态更新进行排队.

一旦完成此操作,此操作就完成了它的逻辑.然后,React框架会发现有状态更新,对其进行处理,并相应地重新呈现组件.


总体而言,你的困惑似乎来自于setTimeout是一个阻挡操作的预期.事实并非如此.它将逻辑安排在以后的某个时间发生,然后释放JavaScript引擎以继续处理.

Javascript相关问答推荐

序列化我的数据并发送httpPost请求后,控制器收到空参数

使用JavaScript重命名对象数组中的键

在时间轴完整日历中显示日期标题

JavaScript文本区域阻止KeyDown/KeyUp事件本身上的Alt GR +键组合

深嵌套的ng-container元素仍然可以在Angular 布局组件中正确渲染内容吗?

单击子元素时关闭父元素(JS)

docx.js:如何在客户端使用文档修补程序

为什么promise对js中的错误有一个奇怪的优先级?

Promise Chain中的第二个useState不更新

构造HTML表单以使用表单数据创建对象数组

简单的PayPal按钮集成导致404错误

JS,当你点击卡片下方的绿色空间,而它是在它的背后转动时,

在JS中拖放:检测文件

Html文件和客户端存储的相关问题,有没有可能?

如何创建返回不带`new`关键字的实例的类

在JS中动态创建对象,并将其追加到HTML表中

为什么当我更新数据库时,我的所有组件都重新呈现?

Phaser3 preFX addGlow不支持zoom

ngOnChanges仅在第二次调用时才触发

如何在独立的Angular 应用程序中添加Lucide-Angel?