Skip to content
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

CSSTransitionGroup transitions don't fire reliably unless transition set on -active class #2104

Closed
jaredatron opened this issue Aug 28, 2014 · 15 comments

Comments

@jaredatron
Copy link

Here is an example of how <ReactCSSTransitionGroup> is explained in the README:

http://jsfiddle.net/deadlyicon/kb3gN/4984/

It works.

Here is that same example except I've added a componentDidMount method that focuses a button within the component being transitioned:

http://jsfiddle.net/deadlyicon/kb3gN/4985/

Notice how the enter transition fails to animate.

This is possibly a browser bug but I thought I'd let you know anyway.

It's also worth noting that this bug can be worked around by moving the transition out of .example-enter and into .example-enter.example-enter-active like so:

http://jsfiddle.net/deadlyicon/kb3gN/4986/

Hope this helps improve React :D

@waldreiter
Copy link
Contributor

Thanks for the fiddle! The bug happens also when the autoFocus attribute gets added to the Close button.

@jaredatron
Copy link
Author

Good find @cody can you link to your fiddle?

@waldreiter
Copy link
Contributor

@waldreiter
Copy link
Contributor

In Firefox this bug is worse. Sometimes the Close button does not close the Modal, because the transition got somehow broken. This happens about half the time.

Adding a timeout seems to prevent the bug:

componentDidMount: function(){
  setTimeout(function() {
    this.getDOMNode().childNodes[0].focus();}.bind(this), 0);
}

@nmn
Copy link
Contributor

nmn commented Sep 4, 2014

something is pretty broken with transitionGroup. I'm stuck where I'm trying to transition between two pages.
First I tried CSSTransitionGroup but that didn't work. So I tried TransitionGroup the lower level api.

Even now, when I first switch from Page A to Page B, none of the designated functions fire. But then, When I switch back from Page B to Page A, suddenly ALL the functions fire twice. So both enter and leave functions fire on BOTH the pages. It's kind of like the original events got saved for later and got stacked up.

Not sure if anyone else has seen this bug, but this is fairly new. I don't think it happened in the last point release of react.

@jonasi
Copy link

jonasi commented Sep 4, 2014

This feels like a browser bug. I ran into the same issue with focus() on componentDidMount, but I was able to reproduce the issue without react, but in a similar setup.

Broken

http://jsbin.com/fumaqarebisu/3/edit

The red box should travel 200px on the y axis, but does not.

Workaround 1

http://jsbin.com/ginamupavuye/1/edit

Notice where the transition is - it's on the .enter.active css rule, not on the .enter

Workaround 2

http://jsbin.com/tutuharaqitu/1/edit

The transitions are the same in the broken state, but the focus() occurs after the initial class addition.

Summary

Workaround 2 would be something that needs to be fixed in react, itself. It seems like focus() is getting called before the transition class is added. Looking at the code, that makes sense: in ReactCSSTransitionGroupChild, the enter transition is being called from the componentDidUpdate lifecycle of the ReactTransitionGroup.

Workaround 1, however, is pretty straightforward for the user to use. A lot of people are probably running into this issue because of the example docs, though.

Update
  • noticed that Workaround 2 doesn't work in Safari - more credence to the notion that is a browser issue.

@nmn
Copy link
Contributor

nmn commented Sep 4, 2014

I don't think it's only a browser bug. This is definitely a bug in the javascript. As I mentioned I'm trying to use the lower level TransitionGroup addon, and NOT CSSTransitionGroup.

This requires four callback functions on the child element - will Enter, did Enter, will Leave and did Leave.

I put all four callbacks and put in thre required code to make them work. I used a setTimeout to call the callback functions, so that the DOM firing events isn't in the loop. I also put a console.log in each method, to track which functions are being called.

Well when I switch from A to B none of the console.logs fire. When I change back, instead of 4 console.logs I get 8. The ones from the first transition AND the ones from the second transition. The functions even start in order, and so I get two sets of transitions firing at the same time. This is all in the domain of javascript.

Additionally the problem is IDENTICAL in safari, chrome and firefox (latest stable of all).

@jonasi
Copy link

jonasi commented Sep 4, 2014

@Naman34 Obviously, it's possible there are multiple issues here. I was responding to the OP whose exact symptoms I had to debug.

It might be easier to see if the issues are related if you had a code sample.

@nmn
Copy link
Contributor

nmn commented Sep 4, 2014

I'll add a code sample. Currently, my issue is in a very big project. I'll put one of Jsbin or something.

Also, I'm only mentioning my error here because when I was using CSSTransitionGroup I was having similar problems, and I think the issues are in the lower level TransitionGroup itself.

@rmosolgo
Copy link

I don't have a ton to add here, but I'll tell my story:

I added a CSSTransitionGroup around a hidden input with autoFocus=true.

At first, I put transition on the non-active classes, as I read in the docs:

.new-pass
  $icon-height: 300px
  height: $icon-height
  overflow-y: hidden

  &.slide-enter
    max-height: 0px
    transition: max-height .3s ease-in-out

    &.slide-enter-active
      max-height: $icon-height

  &.slide-leave
    max-height: $icon-height
    transition: max-height .3s ease-in-out

    &.slide-leave-active
      max-height: 0px

But, on a really old iPad, it gave me a weird jump at the end of the enter animation. Happily, I could reproduce on the emulator. When you tapped "Add a barcode", it would open, then jump closed, then jump open again.

(There's a hidden, auto-focused input there, too. It's supposed to take input from a barcode scanner.)

barcodes-animation

I found this thread and tried moving the transition stuff to the -active classes:

.new-pass
  $icon-height: 300px
  height: $icon-height
  overflow-y: hidden

  &.slide-enter
    max-height: 0px

    &.slide-enter-active
      max-height: $icon-height
      transition: max-height .3s ease-in-out

  &.slide-leave
    max-height: $icon-height

    &.slide-leave-active
      max-height: 0px
      transition: max-height .3s ease-in-out

Then everything was 🍰

@gilbarbara
Copy link

I was having trouble with the -enter transition been skipped with "some" components that use componentWillMount and/or componentDidMount.
Moving the transition to the -enter-active fixed it, although it seems counter-intuitive to me.
Weird!

@nmn
Copy link
Contributor

nmn commented Mar 6, 2015

My last problem was probably a special case. I was unable to detect what caused it to happen. In newer versions of React, CSSTransitionGroup breaks very often. TransitionGroup seems to work fine most of the times though.

I get an error with CSSTransitionGroup saying that the callback failed to fire, so there is at least some sort of detection going on. I think the CSSTransitionGroup should rely on a timeout if the callback fails to fire.

@sophiebits sophiebits changed the title componentDidMount can break <ReactCSSTransitionGroup> CSSTransitionGroup transitions don't fire reliably unless transition set on -active class Apr 1, 2015
@ffxsam
Copy link

ffxsam commented Sep 13, 2015

Notice where the transition is - it's on the .enter.active css rule, not on the .enter

Thank you! Moving transition to my .modal-appear-active class fixed this.

@malectro
Copy link

moving the transition rule to active didn't fix the focus-on-mount issue for me, but deferring the focus call using something like lodash defer made the transitions work again.

@gaearon
Copy link
Collaborator

gaearon commented Oct 27, 2016

Closing since this is not actionable for us.

@gaearon gaearon closed this as completed Oct 27, 2016
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