React js呈现的状态值落后一步

时间:2018-07-12 07:06:16

标签: javascript reactjs

我是新来反应js的人。我已经通过 create-react-app 创建了一个项目,该项目实际上是一个“在线测试应用程序”。我在测试屏幕which looks like this的一个模块中遇到问题。在我的jsx代码中,我正在渲染状态变量的值。

import React, { Component } from 'react';
import { Button, Radio, FormGroup } from 'react-bootstrap';
import Aux from '../../Auxilary/Auxilary';
import { Redirect } from 'react-router-dom';
 
import './TestScreen.css';

class TestScreen extends Component{
    
    state = {
        total_questions:60,
        current_question:1,
        time: 50,
        minutes: null,
        seconds: null
    };
    changeQuestion = () => {
        const question = this.state.current_question;
        this.setState({current_question: question+1});
    };
    componentDidMount(){
        const self = this;
        
        
       let timer = setInterval(function() {
            const newTime = self.state.time -1;
            const minute = Math.floor(self.state.time/60);
            const second = ("0" + self.state.time%60).slice(-2);
            self.setState({minutes: minute, seconds: second, time: newTime},() =>{
                console.log("Value of state Time: " + self.state.time);
            });
            
          
        }, 1000)
    }
   
    render(){
        
        return(
            <Aux>
                <div className="question-timer">
                    <div className="question-number">
                        <h3>Question {this.state.current_question}/{this.state.total_questions}</h3>
                    </div>
                    <div className="test-timer">
                        {this.state.time === 0 ?  <Redirect to='/' /> : console.log("Some Error Occured")}
                        <h3>{this.state.minutes}:{this.state.seconds}</h3>
                    </div>
                </div>
                <div className="test-window">
                    <div className="test-question-statement">
                        <h2><label>Test Question Statement</label></h2>
                    </div>
                    <div className="question-options">
                    
                    <FormGroup>
                        <Radio name="radioGroup">
                            Option 1
                        </Radio>{' '}
                        <Radio name="radioGroup">
                            Option 2
                        </Radio>{' '}
                        <Radio name="radioGroup">
                            Option 3
                        </Radio>
                    </FormGroup>
                    </div>
        {/****************************************Next Question Button************************************************/}
                    <div className="next-question-button-container">
                        <Button onClick={this.changeQuestion} bsClass="xavor-style">Next</Button>
                    </div>
        {/*********************************End of Next Question Button************************************************/}
                </div>
                
            </Aux>

        );
    }
}

export default TestScreen;

我面临的问题是屏幕上显示的时间比更新状态落后一步。由于我正在使用回调函数来更新状态,因此控制台上显示的值是准确的,但JSX中的呈现值却落后了一步。 例如:如果我的控制台打印“ state Time:1”,则渲染的值为0:02。 如何更新状态的呈现值?任何帮助或建议,将不胜感激。预先感谢。

2 个答案:

答案 0 :(得分:2)

当时间为0时,您正在渲染时进行重定向。这就是为什么看不到0:00的原因。而不是直接重定向。在componentDidUpdate中检查渲染之后,是否检查time === 0,是否清除间隔,并更新状态的redirect属性。重新呈现视图时,redirect: true状态将触发实际的重定向。

注意:React的update command (NuGet CLI)是异步的。当状态更新取决于当前状态时,最好使用updater方法。

class TestScreen extends Component{

  state = {
      total_questions:60,
      current_question:1,
      time: 50,
      minutes: null,
      seconds: null,
      redirect: false,
  };

  changeQuestion = () =>
    this.setState((prevState) => ({
      current_question: prevState.current_question + 1
    }));

  componentDidMount() {
    // assign the timer to this.timer, so you can clear it in componentWillUnmount
    this.timer = setInterval(() =>
      this.setState(({ time }) => ({
        minutes: time / 60,
        seconds: ("0" + time % 60).slice(-2),
        time: time - 1
      }))
    , 1000)
  }

  componentDidUpdate() {
    const { time, redirect } = this.state;

    if(!reidrect && time === 0 && ) {
      clearInterval(this.timer);

      this.setState({
        redirect: true
      });
    }
  }

  render() {
    const { time, redirect, minutes, seconds } = this.state;

    // just the relevant JSX parts
    return (
      <div className="test-timer">
        {redirect ?  <Redirect to='/' /> : console.log("Some Error Occured")}
        <h3>{minutes}:{seconds}</h3>
      </div>
    );
  }
}

答案 1 :(得分:0)

将计时器和问题都放在单独的组件中,timerComponent不应呈现。只需渲染您的questionComponent,然后将时间作为道具传递给您的questionComponent。