3

My code is very similar to the example in the official React-Router git repo.

Here is a codepen that shows the problem.

Here is the problem: Instead of waiting for the time specified in the transitionEnterTimeout attribute, the new element is rendered immediately. Then both css animations (enter and leave) run at the same time. After that the previous element gets removed.

I have the same problem locally on a bit more complex setup, that's why I made the simple codepen to see where the problem lies.

I am using the latest versions of all the frameworks (react, react-router, react-addons-css-transition-group)

const App = ({children, location}) => {
    return (
        <ReactCSSTransitionGroup
            component="div"
            transitionName="app"
            transitionEnterTimeout={500}
            transitionLeaveTimeout={500}
        >
            {children && React.cloneElement(children, {
                key: location.pathname,
            })}
        </ReactCSSTransitionGroup>
    );
Chris
  • 2,069
  • 3
  • 22
  • 27

1 Answers1

3

The transitionEnterTimeout does not describe how long to delay before starting the transition. Its value represents how much time to wait before removing the .<name>-enter class from the node.

If you want the enter transition to be delayed, you will need to add a delay to the transition in your CSS.

transition: $type $time $mode $delay;

You will also need to extend the transitionEnterTimeout by the length of the delay.

transitionEnterTimeout={1000}
Paul S
  • 35,097
  • 6
  • 41
  • 38
  • Sorry, but I still dont understand. Regardless of the css animation transitions, the React-Router transition, aka the removing and adding of the route components is overlapping. Even if I set the `transitionLeave` to `false` when you click the routes fast you can see they are overlapping a split-second. Without transition (both set to false) it works, like the router itself, perfectly fine. Is there something else I have to do to make this work, or is the css-transition-group just not good to be used on routes? – Chris Dec 13 '16 at 09:42
  • In the example provided by RR, the page containers are absolutely positioned so that they exist in the same location in the page. – Paul S Dec 13 '16 at 17:28
  • You are right, it did change the behaviour so the two elements can exist above each other so it looks like they fade. But that doesnt change that the bug still exists, that the two elements have a short overlapping period instead of being swapped out like the router normally does. Also I think it would defeat the purpose if I have to fix the css with all the absolute positioning problems. – Chris Dec 13 '16 at 20:40
  • 1
    The `` does not immediately remove an element that no longer exists. I'd recommend reading the source (especially https://github.com/reactjs/react-transition-group/blob/master/src/TransitionGroup.js#L46-L74) if you want a better understanding, but the gist is that the `` renders a ``, which maintains a `state.children` object of child components that are entering and exiting. All of these children are rendered. Once exiting children have finished their animation, they remove themselves from the `state.children` object. – Paul S Dec 13 '16 at 23:36
  • Okay, thanks for the detailed explanation. I guess that way of animating is just not the right thing to use for the router elements. Do you know of any other transition scripts that work better for that kind of thing? – Chris Dec 14 '16 at 10:57
  • There isn't really a good other way to animate components exiting because there is no `unmountComponentAfterAnimation` type of lifecycle method. You end up having to create something that keeps a component rendered after it should have been unmounted in order for its exit animation to occur. I don't really use animations, so I can't make recommendations on other options. Perhaps react-motion's `` can accomplish what you want? – Paul S Dec 15 '16 at 05:39