Sunday, July 31, 2016

Lifecycle events on ReactCSSTransitionGroup's component?

Leave a Comment

Is there a way to get notified of transition lifecycle events on a ReactCSSTransitionGroup's parent component? For example, if I have the following:

<ReactCSSTransitionGroup     transitionName={transitionNames}     transitionEnterTimeout={250}     transitionLeaveTimeout={250}     component={MyParent}>       ... </ReactCSSTransitionGroup> 

I'd like MyParent to accept either lifecycle events, or an isTransitioning-like prop, so that I can (for example) render a different className based on whether a transition is happening or not.. something along the lines of

const MyParent = (props) => {     if (props.isTransitioning) { // or something         return <div className="animating" { ... props } />     } else {         return <div { ... props } />     } } 

Is there a way to make this work? Can I know if a ReactCSSTransitionGroup is currently transitioning? All I can see is that the lifecycle events are fired on the child components entering or leaving the group, and not on the container component itself.

1 Answers

Answers 1

I'm not sure about passing Parent component to the ReactCSSTransitionGroup. I would recommend another approach: simply wrap <MyComponent /> with <ParentComponent /> and setup callback props in <MyComponent /> like so:

Link to the plunkr example -> https://plnkr.co/edit/hSRpiVIVQkZlYjyh2SuD?p=preview

Short explanation: Each item in the list has CSS-class .item

.item {   transition: opacity 250ms ease-in; } 

Once animation for the .item completed React (starting from v15) will fire the onTransitionEnd callback and will pass this information to the parent component.

And I've added callback onBeforeItemTransition to tell the <Parent /> component, that something gonna happen soon, the transition should start.

var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;    var ParentComponent = React.createClass({      render() {        return <MyComponent        onItemTransitionEnd={(item) => {          console.log('Transition end for item', item);        }} />      }  });    var MyComponent = React.createClass({        getInitialState() {      return {        items: ['Item #0']      }    },        getDefaultProps() {      return {        // We need to call this before we are starting animate items        onBeforeItemTransition: function() {          console.log('Transition started!');        },        // This should be called after ctra        onItemTransitionEnd: function() {        }      }    },        addItem() {      var newItems =        this.state.items.concat(['Item #' + (this.state.items.length)]);      this.setState({items: newItems});      this.props.onBeforeItemTransition();    },        render() {            var items = this.state.items.map((item, index) => {        return <div className="item" key={item} onTransitionEnd={this.props.onItemTransitionEnd.bind(this, item)}>          {item}        </div>      });            return <div>      <button onClick={this.addItem}>Add item</button>      <ReactCSSTransitionGroup       transitionName="example"        transitionEnterTimeout={250}        transitionLeaveTimeout={250}>        {items}      </ReactCSSTransitionGroup>        </div>    }      });      ReactDOM.render(    <div>      <h1>Rendered from script.jsx!</h1>      <ParentComponent />    </div>,    document.getElementById('example')  );

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment