javascript 在React中,当props被更改时,await可以阻止render?

eoxn13cs  于 2023-10-14  发布在  Java
关注(0)|答案(2)|浏览(108)

关于React render和await的技术问题
如果我有一个组件,它有一个名为“label”的props,用于设置<p>的文本,如果我按下一个按钮,调用一个设置10秒超时的函数,如果props“label”被更改,而超时仍然有效,会发生什么?<p>值是否会更新?还是会在超时结束后发生?换句话说,当有一个活动的await时,组件是否被锁定?
我可以举一个例子,如果它可以使问题更清楚。

import { Component } from "react";

export default class TestAsyncComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      label: "BEFORE",
    };
  }

  startAsync = async () => {
    console.log("START ASYNC");
    console.log(await this.foo());
  };

  foo = () => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("PROMISE FINISHED");
      }, 5000);
    });
  };

  changeLabel = () => {
    this.setState({ label: "AFTER" }, () => {
      console.log("LABEL CHANGED");
    });
  };

  render() {
    return (
      <div>
        <p>{this.state.label}</p>
        <button
          style={{ width: "100px", height: "50px" }}
          onClick={this.startAsync}
        >
          {"START ASYNC"}
        </button>
        <button
          style={{ width: "100px", height: "50px" }}
          onClick={this.changeLabel}
        >
          {"CHANGE LABEL"}
        </button>
      </div>
    );
  }
}

如果我按下START ASYNC(启动异步)按钮,然后立即按下CHANGE LABEL(更改标签)按钮(等待仍处于活动状态),则标签会更改。我的问题现在更像是:为什么会这样?既然JavaScript是单线程的,那么如果await没有锁定组件,它是如何处理的呢?

2vuwiymt

2vuwiymt1#

如果await没有锁定组件,它是如何处理的?
为什么会这样?没有任何东西在等待startAsync()的调用。(也不应该)。
当您单击按钮来调用startAsync时(按钮 doesn'tshouldn't 等待该调用),异步操作将启动并调用setTimeout。所有这些都不是阻塞的,所以控制权会立即返回给UI。
当您单击按钮调用changeLabel时,它会更新状态并将日志记录到控制台。
过了一会儿,当超时结束时,传递给setTimeout的函数将执行,并将日志记录到控制台。
这里没有发生任何阻塞,也不应该发生。

6rvt4ljy

6rvt4ljy2#

当有一个活动的await时,它不会被锁定,无论如何都会更新该值。你可以在这里看到https://react.dev/learn/state-as-a-snapshot向下滚动,这里有一个例子。我提供的链接是关于此的react文档,有一个例子和解释为什么会发生这种情况,就在这个例子之后,它说:“存储在React中的状态可能在警报运行时已经更改,但它是使用用户与之交互时的状态快照进行调度的!“

相关问题