我想获取数据,如果获取时出错。我想等待1000秒,然后再次获取数据。
问题在于在方法settingTimeout()中this.setState({timerStatus:true});我期望重新渲染整个应用程序并在console.log中渲染超时。但是由于某种原因,它没有这样做。我尝试在setTimeout()中使用this.forceUpdate();没有太多的运气。 React similiar example
this.state = {
retryTimer: 1000,
timerStatus: false,
}
}
componentDidMount(){
if(this.state.timerStatus){
console.log('timeout');
}
this.newGame();
}
newGame =() => {
Axios.get(
this.state.apiBase + 'nexGame',
this.state.headers
)
.then(response =>{
console.log(response)
}
})
.catch(error =>{
this.settingTimeout();
})
}
settingTimeout = () =>{
this.setState({timerStatus: true});
if(this.state.retryTimer === 0){
this.newGame();
}
}
答案 0 :(得分:0)
如果前一个呼叫失败,您似乎想每1s打一次电话,对吗?
我不确定您是否需要重新渲染应用程序才能执行此操作。如果您想重新进行此调用,可以将react生命周期与组件https://reactjs.org/docs/react-component.html#updating
一起使用与:
shouldComponentUpdate(nextProps, nextState) {
if(this.nextState.timerStatus = true) {
setState({ timerStatus: false });
this.newGame();
}
并在函数setTimeout上设置超时,当传递1s时,将timerStatus的状态更改为true。 React将监视此事件,将timerStatus设置为false并重新进行调用。如果通话正常,您将得到答案;否则,您将再次等待1秒钟并重新拨打电话,等等。
答案 1 :(得分:0)
您可以尝试执行以下操作(说明在小提琴下):
let counter = 0;
class App extends React.Component {
timer;
constructor(props) {
super(props);
this.state = {
data: "",
loading: true,
fetchError: false
}
}
componentDidMount() {
/* Simulating a fetch with setTimeout. */
const random = Math.floor(Math.random() * 1000) + 100;
setTimeout(() => {
/* Here you would write .then(). */
if (counter === 2) {
this.setState({loading: false});
}
/* Here you would write .catch(). */
if (counter === 0) {
this.setState({fetchError: true});
this.timer = setInterval(this.handleFetch, 1000);
}
counter++;
}, random);
}
handleFetch = () => {
/* Simulating a fetch with setTimeout. */
const random = Math.floor(Math.random() * 1000) + 100;
setTimeout(() => {
/* This would be the then(), where you save the data. */
if (counter === 2) {
clearInterval(this.timer);
this.setState({loading: false, fetchError: false, data: "YES!!"})
}
/* In this case, if the fetch fails, you do nothing. */
counter++;
}, random);
}
render() {
const {fetchError, loading, data} = this.state;
return (
<React.Fragment>
{loading && fetchError && <p>Error in Fetch</p>}
{loading && !fetchError && <p>Loading</p>}
{!loading && !fetchError && <p>{this.state.data}</p>}
</React.Fragment>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
@import url(https://fonts.googleapis.com/css?family=Montserrat);
body {
font-family: 'Montserrat', sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>
首先,我使用setTimeout
模拟提取。此外,为了模拟提取错误,我使用了counter
变量:当变量达到值2
时,则认为提取正确,否则认为失败。
说,这是怎么回事?在componentDidMount
中运行您的第一个提取操作:而不是if (counter === 2)
,您应该编写您的提取操作的.then()
(因此,在正确运行时)。在该回调中,您只需将this.state.loading
设置为false
。
否则,您应该编写if (counter === 0)
语句,而不是catch()
:在此过程中,您将创建一个interval
,每个handleFetch()
都调用1000ms
函数。请注意,在这种情况下,您将this.state.fetchError
设置为true
:这样可以为用户提供更好的反馈。
现在,在handleFetch()
内执行提取:再次,如果正确结束,则可以将this.state.loading
和this.state.fetchError
设置为false
,并将数据保存到状态。
否则,您只需等待另一个1000ms
进行下一次提取。