ReactJS Transitions - Why doesn't this work?

css-transitions, reactjs

Solution

React is just changing the content of the DOM because that's all that changed. Give the elements unique keys to make them animate.

  if (this.state.showOne)
  {
    result = <div key="one">One</div>
  }
  else 
  {
    result = <div key="two">Two</div>
  }

JSFiddle

Problem

I'd like to transition one element as it changes to another element. I've got 3 examples: - one that works, but uses a list of items that are kept around (jsfiddle) - one that doesnt work, and only keeps one item around, depending on the state (jsfiddle) - another one that doesn't work, that keeps both items around and hides/shows them (jsfiddle using hide/show) What I want is more like the second one, which is a very slight variation of the first attempt that works. Option 1: ``` /** @jsx React.DOM */ var ReactTransitionGroup = React.addons.TransitionGroup; var TodoList = React.createClass({ getInitialState: function() { return {items: ['hello', 'world', 'click', 'me']}; }, handleAdd: function() { var newItems = this.state.items.concat([prompt('Enter some text')]); this.setState({items: newItems}); }, handleRemove: function(i) { var newItems = this.state.items; newItems.splice(i, 1) this.setState({items: newItems}); }, render: function() { var items = this.state.items.map(function(item, i) { return ( <div key={item} onClick={this.handleRemove.bind(this, i)}> {item} </div> ); }.bind(this)); return ( <div> <div><button onClick={this.handleAdd} /></div> <ReactTransitionGroup transitionName="example"> {items} </ReactTransitionGroup> </div> ); } }); var app = React.renderComponent(<TodoList />, document.body); ``` Option 2: JSX that doesn't work, but is closer to what I'd like to do (really, hide one view, and show another) ``` /** @jsx React.DOM */ var ReactTransitionGroup = React.addons.TransitionGroup; var Test = React.createClass({ getInitialState: function() { return {showOne:true} }, onClick: function() { this.setState({showOne:! this.state.showOne}); }, render: function() { var result; if (this.state.showOne) { result = <div ref="a">One</div> } else { result = <div ref="a">Two</div> } return ( <div> <div><button onClick={this.onClick}>switch state</button></div> <ReactTransitionGroup transitionName="example"> {result} </ReactTransitionGroup> </div> ); } }); var app = React.renderComponent(<Test />, document.body); ``` Option 3: Uses hide/show to keep the 2 views around, but still doesn't work. ``` /** @jsx React.DOM */ var ReactTransitionGroup = React.addons.TransitionGroup; var Test = React.createClass({ getInitialState: function() { return {showOne:true} }, onClick: function() { this.setState({showOne:! this.state.showOne}); }, render: function() { var result; var c1 = this.state.showOne ? "hide" : "show"; var c2 = this.state.showOne ? "show" : "hide"; return ( <div> <div><button onClick={this.onClick}>switch state</button></div> <ReactTransitionGroup transitionName="example"> <div className={c1}>One</div> <div className={c2}>Two</div> </ReactTransitionGroup> </div> ); } }); var app = React.renderComponent(<Test />, document.body); ``` So long story short - How can I make a transition execute on switching from one main "component" to another? I don't get why option 1 works, but option 2 doesn't!

Original source