Skip to content

CSSTransitionGroupChild should generate markup with -enter class already applied #719

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
pgherveou opened this issue Dec 26, 2013 · 11 comments

Comments

@pgherveou
Copy link

Hello there,

I am playing with React transition

I noticed that the -enter classe is added only after the element has been inserted into the dom.

https://github.com/facebook/react/blob/master/src/addons/transitions/ReactTransitionableChild.js#L147-L150

I thought the active class was applied when the component was mounted into the dom.

Here is a small demo: http://jsfiddle.net/437Us/1/
I am using componentWillUpdate to make sure the class is applied directly. If you remove it, and use the same
transition mechanism on a more complex layout sometime you will see the page flashing into the screen before the transition starts

@plievone
Copy link
Contributor

plievone commented Jan 3, 2014

Hi, here's a nice explanation of the transition timeline: #587 (comment)

In your jsfiddle the renderApp function will mount the component on first call. On subsequent calls it will just update the already mounted component, that's why you see the need for your componentWillUpdate. If you want to replace the component (to mount it again), try using a different key prop.

@pgherveou
Copy link
Author

Thks @plievone
Actually I am using componentWillUpdate to force the "enter class" on the TransitionChild. Otherwise the class is added just after componentDidMount (see ReactTransitionableChild.js#L147-L150)

Somehow I had to use this trick on my app , to make the animation work properly. Otherwise the entering view was appearing briefly into the view before sliding in from the right.

I can't reproduce this bug in the fiddle maybe because the demo is too simple, I'll see if I can update it to demonstrate my point...

@plievone
Copy link
Contributor

plievone commented Jan 3, 2014

ComponentDidMount should happen on the same tick, so first the elements are inserted, and then its class is modified on the same tick, or at least these commands are flushed to browser's rendering system on the same tick. It would be nice to know if on some occasions (heavy updates?) this could result in a problem you have seen? Perhaps some other callbacks (in other components, in React core?) before that component's componentDidMount could trigger a repaint in the browser via some dom measurement need?

@plievone
Copy link
Contributor

plievone commented Jan 5, 2014

There is indeed a race condition in ReactTransitionableChild. If you add some other component which forces a repaint on componentDidMount, such as accessing this.getDOMNode().offsetHeight, then the ReactTransitionableChild will first flash with default style and -enter class is only added after that, not immediately, and -enter-active after that. For people using jQuery plugins etc these kinds of repaints might happen easily for more complex renders, perhaps needs warning in docs. /cc @petehunt

@pgherveou
Copy link
Author

I updated the fiddle to demonstrate the bug
http://jsfiddle.net/437Us/7/

@plievone
Copy link
Contributor

plievone commented Jan 8, 2014

A brief look at the mounting procedure (https://github.com/facebook/react/blob/23ab30f/src/core/ReactCompositeComponent.js#L688-L720) suggests that to prevent races, transitions should use componentWillMount and setState there, so that the class could be set already on initial render.

@sophiebits sophiebits changed the title ReactTransitionableChild enter class ReactCSSTransitionGroupChild enter class May 18, 2014
@santiagoaguiar
Copy link

Is there any progress on this? ReactCSSTransitionGroup seems a good fit for our cases, but having this issue in multiple places makes it hard to use.

@sophiebits
Copy link
Collaborator

Sorry, no progress on this. It's hard to make this happen automatically with our current architecture.

@sophiebits sophiebits changed the title ReactCSSTransitionGroupChild enter class CSSTransitionGroupChild should generate markup with -enter class already applied Apr 1, 2015
@tyler-dot-earth
Copy link

tyler-dot-earth commented Aug 26, 2016

Would adding initial + finished states (classes) for the transition be easier than adding the enter class on initial render? (basing this on "It's hard to make this happen automatically with our current architecture." by @spicyj in previous post)

Or is there some other workaround for this which I'm not seeing? Or is there a better alternative to ReactCSSTransitionGroup at this point?

EDIT: for the record, my workaround (and this wont work for everyone) is to do something like this:

      <ReactCSSTransitionGroup
        transitionName={{
          enter: styles.enter,
          enterActive: styles['enter-active'],
          leave: styles.leave,
          leaveActive: styles['leave-active'],
        }}
        transitionEnterTimeout={150}
        transitionLeaveTimeout={130}
        styleName="wrapper"
      >
        {components}
      </ReactCSSTransitionGroup>
@keyframes enter {
  0% {
    opacity: 0;
    transform: translateX(-100%);
  }

  100% {
    opacity: 1;
    transform: translateX(0);
  }
}

.wrapper {
  position: relative; /* for absolutely positioned children */

  > * {
    animation: enter;
    animation-duration: 150ms;
  }
}

.enter, .leave {
  /* Eliminates most "popping" from animation */
  position: absolute;
  top: 0;
  width: 100%;
}

.enter {
  /* HANDLEDED IN .wrapper TO PREVENT POP-IN BUG
   * CAUSED BY THIS: https://github.com/facebook/react/issues/719 */
  /*animation: enter;*/
  /*animation-duration: 150ms;*/
}

.enter-active {
}

.leave {
  animation: enter; /* reversed animation-direction for exit */
  animation-direction: reverse;
  animation-duration: 130ms;
}

.leave-active {
}

@gaearon
Copy link
Collaborator

gaearon commented Jan 27, 2017

I’m going to close since we don’t plan any more changes to TransitionGroup in React repo. Instead, it now is maintained by the community, and you can file an issue in the new repository if this is still affecting you. Thanks!

@gaearon gaearon closed this as completed Jan 27, 2017
@cvle
Copy link

cvle commented Feb 1, 2017

Checkout this project as an alternative: https://github.com/wikiwi/react-css-transition

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants