在React.js中的ComponentDidUpdate中设置超时

时间:2018-02-13 11:25:49

标签: javascript reactjs

我坚持自己无法解决的一个问题。也就是说,我正在试图弄清楚在我想改变状态的那一刻如何设置Timeout。换句话说,我想在5秒后改变它,这应该发生在我正在改变状态的地方,即。在ComponentDidUpdate生命周期中。这可能还是我应该重写我的代码?

另外,在下面的代码中将“if”逻辑放在render方法中是一个好习惯吗?

提前谢谢!

import React, { Component } from 'react';
import '../../sass/main.scss';

class TypeAnimation extends Component {
    constructor(props) {
        super(props);
        this.state = {
            sec: 0,
            sec2: 0,
            currentSentence: 0,
            blinker: '|',
            blinker2: null
        };
    }
    componentDidMount() {
        this.firstSentenceInterval = setInterval(() => {
            this.setState({
                sec2: this.state.sec2 + 1,
            });
        }, 100);

        this.textInterval = setInterval(() => {
            this.setState(
                prevState => ({ 
                    sec: prevState.sec !== this.props.text[0].length &&
                         this.state.sec2 === this.props.text[0].length ?
                         prevState.sec + 1 : 0,
                    currentSentence: prevState.sec === this.props.text[0].length ?
                    prevState.currentSentence + 1 : prevState.currentSentence,
                })
            ); 
        }, 100);
    }

    componentDidUpdate() {
        if (this.state.sec2 === this.props.text[0].length &&
            this.state.blinker !== null) { 
            this.setState({    //I would like to change those states but after 5 seconds 
                blinker: null,
                blinker2: '|'
            });
            clearInterval(this.firstSentenceInterval);
        } 
    }


    render() {

        const incomingFirstSen = this.props.text[0];
        const firstSentence = incomingFirstSen.substr(0, this.state.sec2);

        let otherSentences;
        const nextSentences = this.props.text.slice(1);
        const currentText = nextSentences[this.state.currentSentence];

        if (this.state.sec2 !== incomingFirstSen.length) {
            otherSentences = null;
        } else if (this.state.currentSentence !== nextSentences.length) {
            otherSentences = currentText.substr(0, this.state.sec);
        } else {
            clearInterval(this.textInterval);
            otherSentences = nextSentences[nextSentences.length - 1];
        }

        return (
            <div>
                <h2>
                    {firstSentence}
                    <span className="blinker"> {this.state.blinker} </span>
                </h2>
                <h2>
                    {otherSentences}
                    <span className='blinker'> {this.state.blinker2} </span>
                </h2>
            </div>
        );
    }
}

export default TypeAnimation;

2 个答案:

答案 0 :(得分:0)

请勿更新componentDidUpdate中的状态。该组件刚刚渲染,您将再次渲染它。

相反,您应该在componentWillMount中设置状态。只需使用setTimeout中的普通componentWillMount来更新状态。

放置&#34;如果&#34;是正常的渲染函数中的逻辑如果你需要检查当前状态,请不要担心:)

答案 1 :(得分:0)

您的代码段片段有一个导致错误状态值的错误:

print_r($_FILES);

必须重写:

this.firstSentenceInterval = setInterval(() => {
  this.setState({
    sec2: this.state.sec2 + 1,
  });
}, 100);

你的问题:

  

我试图弄清楚在我想要改变状态的时刻如何设置超时

您需要在状态更改时添加观察程序并重新创建计时器(如果已创建):

this.firstSentenceInterval = setInterval(() => {
  this.setState( prevState => {
    sec2: prevState.sec2 + 1,
  });
}, 100);