1

I'm creating a simple app with three states and using React's router with ReactCSSTransitiouGroup. Default behavior of ReactCSSTransitionGroup is simple:

  1. After the click to Link append/prepend new child
  2. New child gets "app-enter" and "app-enter-active" classes
  3. Old child gets "app-leave" and "app-leave-active" classes
  4. After timeout remove the old child

What I'm trying to do is to change this behavior so it can behave like that:

  1. After the click to Link stay in the same state. Just add to the old child classes "app-leave" and "app-leave-active" classes.
  2. After the leave timeout remove the old child and append new child with "app-enter" and "app-enter-active" classes.
  3. After the enter timeout remove it's classes

Is there some easy way how to get this? Thanks!

user2595304
  • 216
  • 1
  • 5
  • 13
  • 1
    I don't think this is a use-case for React transition group. The point of a transition group is to transition children. Since you only want a single child and to animate the CSS class over time, you just want a sequence of prop changes. – Aaron Beall Apr 11 '16 at 15:15
  • Thanks for your answer Aaron, I thought so. Any idea/tip how to achieve this in cooperation with react-router? – user2595304 Apr 12 '16 at 08:51
  • Okay, I went through the documentation and I think it should be possible with react-router's Lifecycle using it's hooks. I will try it :) – user2595304 Apr 12 '16 at 09:18

1 Answers1

0

One simple solution would be to not use a traditional link. If you add a custom event listener you can just start a timeout with startTimeout(namedFunctionToSetLocation, 200ms). I strongly recommend being frugal and using flags to control the state complexity, which will otherwise try and eat you alive.

In more detail:

  1. When someone triggers your event listener, firstly set some state which will add your classes "app-leave" and "app-leave-active". You can do this in a separate function but make sure to bind the function to your component's this so it can access this.state, or pass the state in when rendering.

  2. In that function, you also want to start a timeout, so you can do the next you do of changes after a delay. It's worth generating an ID at this point, or setting a flag, so you can check after the delay that nothing else has begun in that time (if you use one ID variable for all transitions, and just update every time a new one begins, you should have a rock solid check whether, after an async delay, you still care about continuing).

  3. When the timeout is triggered, and you've checked your flag, you can manually trigger your router, or set a new location, however you like.

I've found it useful to use a simple bespoke approach when ReactTransitionGroup isn't a perfect fit. The transition group has nuanced behaviours with ReactRouter v4, and it's completely unnecessary if all you need is a delay or simple class change on click.

Finally, you can also use the normal ReactRouter and ReactTransitionGroup components inside of conditional rendering blocks (like those I just described)- don't pass off that technique, it's as React-ee as it gets.

Olivier Butler
  • 183
  • 2
  • 18