Another way to tackle this scenario could involve switching state after the animation is finished. This method allows you to not only apply transitions but also any other actions you desire (such as JavaScript animations or SMIL). Just remember to include an end callback at the appropriate time :)
Here's a live example on CodePen
Below is the code snippet for reference:
const runCustomAnimation = (node, {property = 'opacity', from, to, duration = 600, post = ''}, end) => {
const difference = to - from;
const startingTime = Date.now();
const animateFrame = ()=>{
const currentTime = Date.now() - startingTime;
if (currentTime >= duration) {
node.style[property] = to + post;
return typeof end == 'function' && end();
}
const value = from + (difference * (currentTime/duration));
node.style[property] = value + post;
requestAnimationFrame(animateFrame);
}
requestAnimationFrame(animateFrame);
}
class CustomComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
isHidden: false
}
this.handleClick = (e)=>{
this.hideElement(e.currentTarget,()=>{
this.setState({isHidden: !this.state.isHidden})
});
};
this.setReference = (n)=>{
n && this.showElement(n);
};
}
render() {
if (this.state.isHidden){
return this.renderCollapsedState();
}
return this.renderActiveState()
}
renderCollapsedState() {
return (
<div
key='b'
style={{opacity: 0}}
ref={this.setReference}
className={`b`}
onClick={this.handleClick}>
<h2>I'm Collapsed</h2>
</div>
)
}
renderActiveState() {
return (
<div
key='a'
style={{opacity: 0}}
ref={this.setReference}
className={`a`}
onClick={this.handleClick}>
<h2>I'm Active</h2>
</div>
)
}
showElement(node, cb) {
runCustomAnimation(node, {from: 0, to: 1}, cb);
}
hideElement(node, cb) {
runCustomAnimation(node, {from: 1, to: 0}, cb);
}
}
ReactDOM.render(<CustomComponent />, document.getElementById('content'));
To ensure the success of this approach, rely solely on state rather than props within your Component. If necessary, make adjustments in the componentWillReceiveProps method when dealing with props.
Updated Version
Check out the updated Codepen link for a clearer demonstration highlighting the advantages of this technique. The transition has been converted into a JavaScript animation, eliminating the need for the transitionend event.