gpt4 book ai didi

javascript - 如何使用 ReactJS 在长时间操作之前立即反馈给用户?

转载 作者:行者123 更新时间:2023-11-30 13:51:33 25 4
gpt4 key购买 nike

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

我有一个 ReactJS 应用程序,当用户单击一个按钮时,我想将按钮文本更改为“工作中...”,以便用户可以看到该应用程序正在处理他们的请求。在呈现更新后的按钮之后,我才想真正开始操作。

我的第一次尝试是使用 componentDidUpdate。 AFAIK,它不应该在渲染之后调用。但这是我的尝试,你可以看到按钮永远不会改变(打开控制台以帮助它花费足够长的时间)。 https://jsfiddle.net/joepinion/0s78e2oj/6/

class LongOperationButton extends React.Component {
constructor(props) {
super(props);
this.state = {
opInProgress: false,
};
}

render() {
let btnTxt = "Start Operation";
if(this.state.opInProgress) {
btnTxt = "Working...";
}

return(
<button
onClick={()=>this.startOp()}
>
{btnTxt}
</button>
);
}

startOp() {
if(!this.state.opInProgress) {
this.setState({opInProgress: true});
}
}

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

function takeALongTime() {
for(let i=1;i<=2000;i++) {
console.log(i);
}
}

ReactDOM.render(
<LongOperationButton op={takeALongTime} />,
document.getElementById('container')
);

下一次尝试我尝试使用 setState 的回调。似乎不太正确,因为它绕过了 componentShouldUpdate,但值得一试:https://jsfiddle.net/joepinion/mj0e7gdk/14/

同样的结果,按钮没有更新。

我在这里错过了什么???

最佳答案

laurent 的评论是正确的。你的代码正在执行 this.props.op,然后立即更新状态。 TakeALongTime 需要在完成时发出信号。

function takeALongTime() {
return new Promise(resolve => {
setTimeout(resolve, 2000);
});
}

componentDidUpdate需要等到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});
});
}
}

关于javascript - 如何使用 ReactJS 在长时间操作之前立即反馈给用户?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58136652/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com