I'm having problems with complex animations, where one component has to finish animating before another. In this example, I'm trying to fade out a component before another component is faded in. I can't use react-motion or any third party library, and can't rely on css transitions. Here is a working example highlighting the problem. Please note that the 'Editor' and 'Display' components aren't always of the same height.
Javascript
var Editor = React.createClass({
render: function() {
return <input type="text" defaultValue={this.props.name} />
}
});
var Display = React.createClass({
render: function() {
return <div>{this.props.name}</div>;
}
});
var Row = React.createClass({
getInitialState: function() {
return {
isEditing: false
}
},
updateRow: function() {
this.setState({isEditing: !this.state.isEditing});
},
render: function() {
return (
<div className="row" onClick={this.updateRow}>
<React.addons.TransitionGroup>
{
this.state.isEditing ?
<Fade key="e"><Editor name={this.props.name}/></Fade> :
<Fade key="d"><Display name={this.props.name}/></Fade>
}
</React.addons.TransitionGroup>
</div>);
}
});
var Table = React.createClass({
render: function() {
return (
<div className="row" onClick={this.updateRow}>
<Row name="One" />
<Row name="Two" />
<Row name="Three" />
<Row name="Four" />
</div>);
}
});
var Fade = React.createClass({
componentWillEnter: function(callback) {
var container = $(React.findDOMNode(this.refs.fade));
container.animate({
opacity:1
}, callback);
},
componentWillLeave: function(callback) {
var container = $(React.findDOMNode(this.refs.fade));
container.animate({
opacity:0
}, callback);
},
render: function() {
return(<div className="fade" ref="fade">
{this.props.children}
</div>)
}
});
ReactDOM.render(
<Table />,
document.getElementById('container')
);
CSS
.row {
background-color: #c9c9c9;
border-bottom: 1px solid #dedede;
padding: 5px;
color: gray;
cursor:pointer;
}
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js">
</script>
<div id="container">
</div>