Another approach to this situation may be to change state after the animation is complete. The advantages of this are that you can apply not only transitions, but also any actions you want (js-animation, smile, etc.), the main thing is to remember to call the end callback;)
Here is a working example of CodePen
And here is a sample code:
const runTransition = (node, {property = 'opacity', from, to, duration = 600, post = ''}, end) => { const dif = to - from; const start = Date.now(); const animate = ()=>{ const step = Date.now() - start; if (step >= duration) { node.style[property] = to + post; return typeof end == 'function' && end(); } const val =from + (dif * (step/duration)); node.style[property] = val + post; requestAnimationFrame(animate); } requestAnimationFrame(animate); } class Comp extends React.Component { constructor(props) { super(props); this.state = { isCollapsed: false } this.onclick = (e)=>{ this.hide(e.currentTarget,()=>{ this.setState({isCollapsed: !this.state.isCollapsed}) }); }; this.refF = (n)=>{ n && this.show(n); }; } render() { if (this.state.isCollapsed){ return this.renderCollapsed(); } return this.renderActive() } renderCollapsed() { return ( <div key='b' style={{opacity: 0}} ref={this.refF} className={`b`} onClick={this.onclick}> <h2>I'm Collapsed</h2> </div> ) } renderActive() { return ( <div key='a' style={{opacity: 0}} ref={this.refF} className={`a`} onClick={this.onclick}> <h2>I'm Active</h2> </div> ) } show(node, cb) { runTransition(node, {from: 0, to: 1}, cb); } hide(node, cb) { runTransition(node, {from: 1, to: 0}, cb); } } ReactDOM.render(<Comp />, document.getElementById('content'));
And, of course, for this approach to work, your only opportunity is to relay the state, not the Component attribute, which you can always set in the componentWillReceiveProps method if you have to deal with them.
Update
The Codepen link has been updated with a clearer example that shows the benefits of this approach. The transition has been changed to javascript animation without relying on the transition event.
source share