Javascript 如何在长时间操作之前使用ReactJS向用户提供即时反馈?

Javascript 如何在长时间操作之前使用ReactJS向用户提供即时反馈?,javascript,reactjs,Javascript,Reactjs,注意:在下面标记Michael Cox的答案是正确的,但是您也应该阅读答案下面的讨论,这说明componentDidMount显然是在浏览器渲染之前调用的 我有一个ReactJS应用程序,当用户单击一个按钮时,我想将按钮文本更改为“Working…”,这样用户就可以看到应用程序正在处理他们的请求。在更新的按钮被渲染之后,然后并且只有在那时,我才想真正开始操作 我的第一次尝试是使用componentDidUpdate。好的,在渲染之后才应该调用它。但这是我的尝试,您可以看到按钮从未改变(打开控制台

注意:在下面标记Michael Cox的答案是正确的,但是您也应该阅读答案下面的讨论,这说明componentDidMount显然是在浏览器渲染之前调用的

我有一个ReactJS应用程序,当用户单击一个按钮时,我想将按钮文本更改为“Working…”,这样用户就可以看到应用程序正在处理他们的请求。在更新的按钮被渲染之后,然后并且只有在那时,我才想真正开始操作

我的第一次尝试是使用componentDidUpdate。好的,在渲染之后才应该调用它。但这是我的尝试,您可以看到按钮从未改变(打开控制台以帮助它花费足够长的时间)

class LongOperationButton扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
opInProgress:错,
};
}
render(){
让btnTxt=“开始操作”;
if(this.state.opInProgress){
btnTxt=“工作…”;
}
返回(
this.startOp()}
>
{btnTxt}
);
}
startOp(){
如果(!this.state.opInProgress){
this.setState({opInProgress:true});
}
}
componentDidUpdate(){
if(this.state.opInProgress){
this.props.op();
this.setState({opInProgress:false});
}
}
}
函数takeALongTime(){

for(设i=1;ilaurent的评论无效。您的代码正在执行this.props.op,然后立即更新状态。
TakeALongTime
需要在完成时发出信号

function takeALongTime() {
    return new Promise(resolve => {
    setTimeout(resolve, 2000);
  });
}
componentdiddupdate
需要等到
op
完成后才能设置状态

  componentDidUpdate() {
    if(this.state.opInProgress) {
      this.props.op().then(() => {
        this.setState({opInProgress: false});
      });
    }
  }
(这是您的第一个示例。)


您也可以通过回调来实现这一点

function takeALongTime(cb) {
    setTimeout(cb, 1000);
}

componentDidUpdate() {
  if(this.state.opInProgress) {
    var parentThis = this;
    this.props.op(function() {
      parentThis.setState({opInProgress: false});
    });
  }
}

for(设i=1;i)您正在阻止渲染循环,因此不会发生任何事情。您需要以异步方式执行长时间操作,或者使用worker。感谢您的回答。您的代码中的差异似乎是使用了回调函数所示的setTimeout方法。如果我添加了承诺,但保留循环代码(因为这更像是我的代码,一系列需要几秒钟的指令)它仍然不起作用。所以我需要做一个超时,只是为了让我的代码在dom渲染后运行吗?setTimeout只是我简单的方式,就像计算机正在做一些工作一样。你可以这样做
函数takeALongTime(cb){(让i=1;这是一个完全前端的应用程序。我想这个问题说明的是componentDidMount在虚拟DOM更新后解决,但不一定在浏览器的DOM之前解决。你同意吗?如果同意,请将这一事实添加到上面的答案中(触及问题的核心)我很乐意接受。我认为问题在于
componentdiddupdate
render
之前运行,因此您实际上是在让计算机工作,并在呈现更新的组件之前完成操作。这导致我重新解释此文档,其中说明componentdiddupdate,“将此作为在组件更新后对DOM进行操作的机会。”我一直认为这意味着浏览器DOM是最新的,但可能这意味着相反-内部状态和(可能)虚拟DOM已更新,但浏览器DOM未更新。
function takeALongTime(cb) {
    setTimeout(cb, 1000);
}

componentDidUpdate() {
  if(this.state.opInProgress) {
    var parentThis = this;
    this.props.op(function() {
      parentThis.setState({opInProgress: false});
    });
  }
}