关于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没有锁定组件,它是如何处理的呢?
2条答案
按热度按时间2vuwiymt1#
如果await没有锁定组件,它是如何处理的?
为什么会这样?没有任何东西在等待
startAsync()
的调用。(也不应该)。当您单击按钮来调用
startAsync
时(按钮 doesn't 和 shouldn't 等待该调用),异步操作将启动并调用setTimeout
。所有这些都不是阻塞的,所以控制权会立即返回给UI。当您单击按钮调用
changeLabel
时,它会更新状态并将日志记录到控制台。过了一会儿,当超时结束时,传递给
setTimeout
的函数将执行,并将日志记录到控制台。这里没有发生任何阻塞,也不应该发生。
6rvt4ljy2#
当有一个活动的await时,它不会被锁定,无论如何都会更新该值。你可以在这里看到https://react.dev/learn/state-as-a-snapshot向下滚动,这里有一个例子。我提供的链接是关于此的react文档,有一个例子和解释为什么会发生这种情况,就在这个例子之后,它说:“存储在React中的状态可能在警报运行时已经更改,但它是使用用户与之交互时的状态快照进行调度的!“