title: How to properly implement React Transition Group for Page Transitions
body: <p>I've been tearing my hair out all day trying to get this to work.  What I'm noticing is that for whatever reason, the transition classes (classNames="fade") never get applied to the page elements.  So when I navigate from one page to another, for a brief period (the timeout period) both of the page components will be displayed. </p>
  
  <p><strong>What I should have for 600ms...</strong></p>
  
  <pre><code>&lt;div class="RTG"&gt; 
      &lt;div class="page fade-appear fade-enter fade-enter-active"&gt; &lt;!-- 
  destination component HTML --&gt;&lt;/div&gt;
      &lt;div class="page fade-exit fade-exit-active"&gt; &lt;!-- start component HTML --&gt;&lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p><strong>What I get is..</strong></p>
  
  <pre><code>&lt;div class="RTG"&gt;
     &lt;!-- "fade..." classes never applied to the child nodes" --&gt;
     &lt;div class="page"&gt; &lt;!-- destination component HTML --&gt;&lt;/div&gt;
     &lt;div class="page"&gt; &lt;!-- start component HTML --&gt;&lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>And then after the 600ms timeout, I'm left with...</p>
  
  <pre><code>&lt;div class="RTG"&gt;
     &lt;div class="page"&gt; &lt;!-- destination component HTML --&gt;&lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p><strong>NOTE 1</strong>: I put the "RTG" className on the TransitionGroup component simply to verify that my "page" class components are actually direct descendants of the TransitionGroup component.  Doesn't exist for any other reason.</p>
  
  <p><strong>NOTE 2</strong>: I'm using react-transition-group@2.4.0 because I have a compatibility issue with the latest version.</p>
  
  <p><strong>AppRouter.js</strong></p>
  
  <pre><code>import PrivateRoute from './PrivateRoute';
  import PublicRoute from './PublicRoute';
  import { CSSTransition, TransitionGroup } from 'react-transition-group'
  
  
  
  const AppRouter = () =&gt; (
      &lt;Router history={history}&gt;
          &lt;Route render={({location}) =&gt; {
              return (
                  &lt;TransitionGroup className="RTG"&gt;
                  &lt;CSSTransition 
                      key={location.key}
                      timeout={600}
                      classNames="fade"
                  &gt;
                      &lt;Switch location={location}&gt;
                          &lt;PublicRoute path="/" component={LoginPage} exact={true} /&gt;
                          &lt;PrivateRoute path="/dashboard" component={ExpenseDashboardPage} /&gt;
                          &lt;PrivateRoute path="/create" component={AddExpensePage} /&gt;
                          &lt;PrivateRoute path="/edit/:id" component={EditExpensePage} /&gt;
                          &lt;Route component={NotFoundPage} /&gt;
                      &lt;/Switch&gt;
                  &lt;/CSSTransition&gt;
             &lt;/TransitionGroup&gt;
              );
          }} /&gt;
  
      &lt;/Router&gt;
  );
  
  
  export default AppRouter;
  </code></pre>
  
  <p><strong>PrivateRoute.js</strong></p>
  
  <pre><code>export const PrivateRoute = ({ 
      isAuthenticated, 
      component: Component,
      ...rest
  }) =&gt; (
      &lt;Route {...rest} component={(props) =&gt; (
          isAuthenticated ? (
              &lt;div className="page"&gt;
                  &lt;Header /&gt;
                  &lt;Component {...props} /&gt;
              &lt;/div&gt;
          ) : (
              &lt;Redirect to="/" /&gt;
          )
      )} /&gt;
  );
  
  const mapStateToProps = (state) =&gt; ({
      isAuthenticated: !!state.auth.uid
  });
  
  export default connect(mapStateToProps)(PrivateRoute);
  </code></pre>
  
  <p><strong>PublicRoute.js</strong></p>
  
  <pre><code>export const PublicRoute = ({ 
      isAuthenticated, 
      component: Component,
      ...rest
  }) =&gt; (
      &lt;Route {...rest} component={(props) =&gt; (
          isAuthenticated ? (
              &lt;Redirect to="/dashboard" /&gt;
          ) : (
              &lt;div class="page"&gt;
                  &lt;Component {...props} /&gt;
              &lt;/div&gt;
          )
      )} /&gt;
  );
  
  const mapStateToProps = (state) =&gt; ({
      isAuthenticated: !!state.auth.uid
  });
  
  export default connect(mapStateToProps)(PublicRoute);
  </code></pre>
  
  <p><strong>Applicable CSS Styles</strong></p>
  
  <pre><code>
  .page {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
  }
  
  .fade-appear,
  .fade-enter {
      opacity: 0;
      z-index: 1;
  }
  
  .fade-appear-active,
  .fade-enter.fade-enter-active {
      opacity: 1.0;
      transition: opacity 300ms linear 150ms;
  }
  
  .fade-exit {
      opacity: 1.0;
  }
  
  .fade-exit.fade-exit-active {
      opacity: 0;
      transition: opacity 150ms linear;
  }
  </code></pre>