Pregunta

Me gustaría transitar un elemento a medida que cambia a otro elemento.

Tengo 3 ejemplos:

Lo que quiero es más como el segundo, que es una variación muy leve del primer intento que funciona.

Opción 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 que no funciona, pero está más cerca de lo que me gustaría hacer (realmente, ocultar una vista y mostrar otra)

/** @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);

Opción 3: Utiliza Ocultar / Mostrar para mantener las 2 vistas, pero aún así no funciona.

/** @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);

Tan larga historia corta: ¿cómo puedo hacer que una transición se ejecute en la conmutación de un "componente" principal a otro? No entiendo por qué funciona la opción 1, ¡pero la opción 2 no!

¿Fue útil?

Solución

Reaccionar está cambiando el contenido de la DOM porque eso es todo lo que cambió.Dale las llaves únicas de los elementos para hacerlos animar.

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

jsfiddle

Otros consejos

Usé la respuesta de Michelle Treys para resolver un problema similar usando React-Router (1.0.1).No está claro de la API que se necesita la clave.Yo estaba siguiendo la sugerencia de reaccionar en los enrutadores para que los niños de rutas en un padre de la siguiente manera:

render() {
    return (
        <div id='app-wrapper'>
          <ReactTransitionGroup component='div' className='transition-wrapper'>
            {this.props.children}
          </ReactTransitionGroup>
        </div>
    );
  }

Sin embargo, el componentewillenter solo se activó en la carga de la página.Siguiendo la solución de Michelle, cloné a los niños según las actualizaciones de reacción-enrutador y agregué una clave de la siguiente manera:

render() {

    const { location } = this.props;

    return (
        <div id='app-wrapper'>
          <ReactTransitionGroup component='div' className='transition-wrapper'>
            {React.cloneElement(this.props.children, {
              key: location.pathname,
            })}
          </ReactTransitionGroup>
        </div>
    );
  }

Gracias por la solución.Saludos

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top