繁体   English   中英

当React.js组件更新时切换CSS类

[英]Toggling a CSS class when a React.js component gets updated

我做了一个简单的React.js状态组件,显示了一个计数器,计数器每秒更新一次。 我想对该计数器实现滚动效果,使每次计数器增加时新数字从顶部向下滚动。 请检查我在Codepen上的以查看该项目的外观。 我的问题专门针对您将在柜台右侧看到的数字。 您会注意到,有两个数字互相重叠,接下来要显示的数字(与组件状态绑定)位于当前可见的数字上方。 这两个数字都具有CSS transform属性,现在,我想做的就是每当新数字增加时在Y轴上平移这些数字。 这是组件的代码:

var ReactCounter = React.createClass({
newFirstDigit: 0,
currentFirstDigit: 0,
currentSecondDigit: 0,  
scrollFirstDigit: false,

// Set initial state with counter not running
getInitialState: function() {
    return {
        running: false,
        newSecondDigit: 0,
        scrollSecondDigit: false,
    }
},

// Called as soon as Counter is added to the DOM
componentDidMount: function() {
    this.interval = setInterval(this.timeCounter, 1000);
},

// Called as soon as Counter is removed from the DOM
componentWillUnmount: function() {
    clearInterval(this.interval);
},

// Called as soon as Counter is updated
componentDidUpdate: function() {
    if (this.currentSecondDigit != this.state.newSecondDigit) {
        // add scroll class
        this.setState ({
            scrollSecondDigit: true,
        })
        this.currentSecondDigit = this.state.newSecondDigit;
    }

    if (this.currentSecondDigit == this.state.newSecondDigit) {
        // remove scroll class
        this.setState ({
            scrollSecondDigit: false,
        })
    }

    if (this.currentFirstDigit !== this.newFirstDigit) {
        // add scroll class
        this.scrollFirstDigit = true;
        this.currentFirstDigit = this.newFirstDigit;
    }

    if (this.currentFirstDigit === this.newFirstDigit) {
        // remove scroll class
        this.scrollFirstDigit = false;
    }

    if (this.state.newSecondDigit == 10) {
        this.newFirstDigit++;
    }

    if (this.state.newSecondDigit == 10) {
        this.setState({
            newSecondDigit: 0,
        });
        this.currentSecondDigit = 0;
    }

    // Stop and reset counter when it gets to 60
    if (this.newFirstDigit == 6) {
        if (this.state.newSecondDigit == 0) {
            this.setState({ 
                running: false,
                newSecondDigit: 0
            });
            this.newFirstDigit = 0;
            this.currentFirstDigit = 0;
            this.currentSecondDigit = 0;
        }
    }
},

timeCounter: function() {
    if (this.state.running) {
        this.setState({
            newSecondDigit: this.state.newSecondDigit + 1,  
        });
    }
},

startCounter: function() {
    this.setState({ 
      running: true,
      previousTime: Date.now(),
    });
},

stopCounter: function() {
    this.setState({ 
        running: false
    });
},

resetCounter: function() {
    this.setState({
      newSecondDigit: 0,
      previousTime: Date.now(),
    });
    this.newFirstDigit = 0;
    this.currenFirstDigit = 0;
    this.currentSecondDigit = 0;
},

render: function() {
    var scrollFirstDigit = this.scrollFirstDigit === true ? 'scroll' : '';
    var scrollSecondDigit = this.state.scrollSecondDigit === true ? 'scroll' : '';

    return (
        <div className="counter-container">
            <div className="numbers-container">
                <div className="number-container one">
                    <div className={"number current " + scrollFirstDigit}>
                        {this.newFirstDigit}
                    </div>
                    <div className={"number previous " + scrollFirstDigit}>
                        {this.currentFirstDigit}
                    </div>
                </div>
                <div className="number-container two">
                    <div className={"number current " + scrollSecondDigit}>
                        {this.state.newSecondDigit}
                    </div>
                    <div className={"number previous " + scrollSecondDigit}>
                        {this.currentSecondDigit}
                    </div>
                </div>
            </div>
            <div className="buttons-container">
                {this.state.running ? <button className="btn stop" onClick={this.stopCounter}>Stop</button> : <button className="btn start" onClick={this.startCounter}>Start</button> }
                <button className="btn reset" onClick={this.resetCounter}>Reset</button>
            </div>
        </div>
    ); 
}

})

ReactDOM.render( <ReactCounter />, document.getElementById('app-container') );

您将看到我正在尝试在componentDidUpdate方法中添加和删除CSS类。 我也在componentWillUpdate方法中尝试过,但是两种解决方案均无法正常工作。 您认为实现所需滚动效果的最佳方法是什么?

根据我的理解,您想根据已创建的scrollFirstDigitscrollSecondDigit变量更改CSS类(将scroll类添加到类列表中)。 在React中,我经常使用classnames模块来做这样的事情。 例如,以下可能是您感兴趣的东西:

var classnames = require('classnames');
...
<div className={classnames({ 'number current': true, 'scroll': this.state.scrollFirstDigit === true})}>;

因此,您只需更改状态对象即可切换所需的CSS类(因为它将触发重新渲染并导致类的重新评估)。 您可以在模块github页面上查看更多示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM