React动画同步



我有以下React组件:

var Hello = React.createClass({
    getInitialState: function() {
        return {
            visibility: 'visible'
        };
    },
    toggleState: function() {
        if (this.state.visibility === 'visible') {
            this.setState({visibility: 'hidden'});
        } else {
            this.setState({visibility: 'visible'});
        }
    },
    componentDidMount: function () {
        var self = this;
        setInterval(function() {
            self.toggleState();
        }, 5000);
    },
    render: function() {
        return <div className={"animated " + (this.state.visibility === 'visible' ? 'fadeIn' : 'fadeOut')}>{this.state.visibility}</div>;
    }
});

看这里的小提琴。

基本上,我通过state属性visibility使用animate.css来控制显示的字符串和组件可见性。

副作用是,当组件逐渐消失时,它显示为"隐藏",然后开始隐藏。我想早点开始动画,只有完成后,才能更改字符串,这样"隐藏"就永远不会真正显示。

实现这种同步的最佳方式是什么?

隐藏动画完成后更改状态的最佳方法是侦听animationend事件。由于只有当组件具有hidden可见性状态时才需要更改文本状态,因此应在隐藏动画完成后立即将其更改,并在开始动画时更改回visible

text:扩展state

getInitialState: function() {
  return {
    visibility: 'visible',
    text: 'visible'
  }
}

所以你应该在componentDidMount:中添加监听器

componentDidMount: function() {
  this.refs.animated.addEventListener('animationend', this.toggleText); // add ref="animated" element
  // rest code
}

添加toggleText方法更改动画端的文本状态:

toggleText: function() {
  if (this.state.visibility === 'hidden') { // change only on hidden state
    this.setState({
      text: 'hidden'
    });
  }

}

并在显示动画开始时将文本更改为visible,因此:

toggleState: function() {
  if (this.state.visibility === 'visible') {
    this.setState({visibility: 'hidden'}); // text should not be changed immediately
  } else {
    this.setState({visibility: 'visible', text: 'visible'}); // change the text on show animation start
  }

}

这是完整的小提琴

我的解决方案是使用ref"手动"将组件的文本和可见性与setTimeout:同步

render: function() {
  return <div ref="hello">visible</div>;
}
componentWillUpdate: function(next_props, next_state) {
  var self = this;
  if (next_state.visibility === 'visible') {
    this.refs.hello.className = 'animated fadeIn';
    this.refs.hello.innerHTML = 'visible';
  } else {
    this.refs.hello.className = 'animated fadeOut';
    setTimeout(function(){
      self.refs.hello.innerHTML = 'hidden';
    }, 1000);
  }
},

在这里打闹。

最新更新