React-transition-group: enter and enter-active applied simultaneously

Created on 7 Nov 2017  路  20Comments  路  Source: reactjs/react-transition-group

with CSSTransition it seems enter and enter-active are applied simultaneously. is that correct? which means the following doesn't work..

div {
    transition: opacity 1s;

    &.fade-enter {
        opacity: 0;
    }

    &.fade-enter-active {
        opacity: 1;
    }
}

and instead must be..

div {
    transition: opacity 1s;

    &.fade-enter {
        opacity: 0.01;
    }

    &.fade-enter-active {
        opacity: 1;
    }
}

with ng-animate starting at opacity: 0 works, i'm guessing angular applies enter-active after enter ie- next tick. would it be possible to do the same?

Most helpful comment

Try not adding the css transition: property to the appear/enter classes, it should only be on the appearActive/enterActive classes, that worked for me ;)

All 20 comments

The active classes are added on the next tick, opacity: 0 works in my tests (generally that's what I use)

I confirm that this happens to me too

can you provide a repro?

I'll try to make one, meanwhile i made a workaround using animation on enter class

This is also happening to me (for an appear on a CSSTransition) - if I wrap the call to this.props.onEntering(node, appearing) in a setTimeout(..., 50), the enter/appear transition works as expected

In a project using [email protected], testing in Chrome

I can confirm that it happens during the same tick in a case when animated content has an input with autoFocus prop.

Try not adding the css transition: property to the appear/enter classes, it should only be on the appearActive/enterActive classes, that worked for me ;)

@Adrxx that indeed fixes the issue for me. @rr-kalbeck see the codesandbox example from the docs. https://codesandbox.io/s/00rqyo26kn?module=%2Fstyles.css

Doesn't always work:

.fade {
  transition: opacity 500ms ease-in;
}
.fade-enter {
  opacity: 0.01;
}
.fade-enter-active {
  opacity: 1;
}

Better:

.fade-enter {
  opacity: 0.01;
}
.fade-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}

Can you provide a demo for this issue? It should always work, if you add a className to the CSSTransition or its immediate child, it should stay on the entire time.

Well you can see it in the docs example not staying on the entire time right? https://codesandbox.io/s/00rqyo26kn

Please be more specific, what's actually happening vs. what you're expecting. In our example fade class is never applied, the prop classNames (with the "s") defines that all transition-related classes should start with fade-. The list-group-item class of the <ListGroupItem> component stays on the whole time, fade-* classes are always _appended_ to it, they never replace it.

Also, Bootstrap's CSS hides elements with the class fade, so if you're testing it on our example, use a different class.

Sorry I misunderstood. I misread className for classNames in:

Can you provide a demo for this issue? It should always work, if you add a className to the CSSTransition or its immediate child, it should stay on the entire time.

So I thought you meant the fade class (not fade-*) should stay on the entire time if you provide it with classNames. Does that explain my https://github.com/reactjs/react-transition-group/issues/246#issuecomment-383496078 ?

In our example fade class is never applied, the prop classNames (with the "s") defines that all transition-related classes should start with fade-. The list-group-item class of the component stays on the whole time, fade-* classes are always appended to it, they never replace it.

Yeah that's clear now, thanks :)

Please be more specific, what's actually happening vs. what you're expecting.

I think the OP expected something like this to work:

https://codesandbox.io/s/k0m40953mo?module=%2Fstyles.css

.item {
  transition: opacity 500ms ease-in;
}
.fade-enter {
  opacity: 0.01;
}
.fade-enter-active {
  opacity: 1;
}

Which indeed works in the isolated example, but did not work in my project. When mounting a big Modal it did not fade in the first time (it did fade in and out unmounting and re-mounting it a second time). I tried to isolate the problem but I can't reproduce it in the code sandbox.

Putting the transition on the fade-enter-active instead fixed the issue for me. I can't figure out why.

So I thought you meant the fade class (not fade-*) should stay on the entire time if you provide it with classNames. Does that explain my https://github.com/reactjs/react-transition-group/issues/246#issuecomment-383496078?

Yep! 猸愶笍 I see where the misunderstanding was, we should make that more clear in the docs, because it's easy to mistake classNames for className.

If you have that project available somewhere I can check it out.

Closing this until a repro is provided. But I'll be happy to help with your specific issue @teameh.

No worries. My issue was solved by applying the transition to the active class.

My decision:

 .enter {
    transform: translateY(-10px);
    opacity: 0;
    transition: 0.4s; <---- delete here
 }

 .enter-active {
    transform: translateY(0);
    opacity: 1;
    transition: 0.4s; <---- put here
 }

@SkutinAnton yep, this is the correct conclusion, I edited the docs to make this more clear. 5c186f1ec96bbe1eec0c5d5c2d514731adbddc01 In your case .enter defines initial styles, which should be applied immediately because .enter-active is applied on the next tick, i.e. immediately afterwards. Full explanation below:


The reason why you should define transition only for *-active classes is because *-enter/*-exit classes define which styles you're starting from, so you'll usually want these styles to be applied _immediately_. If you have transition defined at all times, this could cause transitions to misbehave if they're not _symmetrical_, depending on your goal, and by "not symmetrical" I mean that styles in *-enter-active/*-enter-done are not the same as *-exit, and/or styles *-exit-active/*-exit-done are not the same as *-enter.

When they are symmetrical, there is usually no problem because the issue is hidden, let's describe the timeline for a simple fading transition when the CSS property transition is being defined at all times:

  1. *-enter is applied, the component starts transitioning to opacity: 0
  2. *-enter-active is applied on the next tick, the component immediately starts transitioning to opacity: 1, essentially ignoring *-enter because it didn't have time to transition

    • this is not a problem if *-exit-active/*-exit-done is the same as *-enter, but if it isn't you might want a different behavior

  3. *-enter-done is applied, the component stays at opacity: 1
  4. *-exit is applied, the component continues from opacity: 1
  5. *-exit-active is applied on the next tick, the component immediately starts transition to opacity: 0

    • this is not a problem here because *-enter-done is the same as *-exit-active, but if it isn't you might want a different behavior

I hope it's more clear now 馃槃

@silvenon, thanks for the explanation.

But I am experiencing a weird behavior with CSSTransition. For my use-case *-enter class is never getting applied to the element and *-enter-active is applied directly.

Due to this very reason, my initial style defines in *-enter is never getting applied. On the other hand *-end class is getting applied properly.

Can somebody help me with this issue? I am adding screenshots of the behavior:

Only success-enter-active class is applied:

image

Both success-exit and success-exit-active classes are applied:

image

PS: I am following the official docs which use v2.7.0 while I am using v4.4.1 for react-transition-group.

That鈥檚 incorrect behavior, please provide a repro so we can help and open a new issue because it鈥檚 not related to this one.

I assume that you鈥檙e changing the transitioning element mid-transition, probably accidentally if you didn鈥檛 expect this, but I have to see the repro to know for sure.

Was this page helpful?
0 / 5 - 0 ratings