我有以下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);
}
},
在这里打闹。