2

Hi I cannot get React Transition Group working at all. Can anyone take a look at this and see why it will not work? The links pull in the components correctly but there are no transitions. No transition coming in or going out and the console.log doesn't fire. I do get a depreciation warning in console but everything is up to date and I'm not sure if that would cause it to stop working or not. I am at a loss so any help would be really appreciated. Thank you.

import * as React from 'react'
import {
    HashRouter as Router,
    Link,
    Switch,
    Route,
    Redirect,
    useParams,
    useLocation
} from "react-router-dom";
import {TransitionGroup, CSSTransition} from "react-transition-group";


const TransGroup = () =>{

    const location = useLocation();

    return(
        <>
            <div className={"w-full h-full"}>
        <Router>
            <div className={"fill w-full"}>

                <ul className={"nav overflow-hidden mb-8 flex "}>
                    <li><Link className={"bg-white p-8 m-8 text-black inline-block"} to={"/"}>Red</Link></li>
                    <li><Link className={"bg-white p-8 m-8 text-black inline-block"} to={"/purple"}>Purple</Link></li>
                    <li><Link className={"bg-white p-8 m-8 text-black inline-block"} to={"/blue"}>Blue</Link></li>
                    <li><Link className={"bg-white p-8 m-8 text-black inline-block"} to={"/yellow"}>Yellow</Link></li>
                    <li><Link className={"bg-white p-8 m-8 text-black inline-block"} to={"/pink"}>Pink</Link></li>
                    <li><Link className={"bg-white p-8 m-8 text-black inline-block"} to={"/aqua"}>Aqua</Link></li>

                </ul>
            </div>
        </Router>
        <div className={"fill content w-full h-full"}>
            <TransitionGroup>
                <CSSTransition
                    timeout={5000}
                
                    onEnter={() => {
                        console.log('FIRED!');
                    }}
                    classNames={{
                        appear: 'my-node-appear',
                        appearActive: 'my-node-active-appear',
                        appearDone: 'my-node-done-appear',
                        enter: 'my-node-enter',
                        enterActive: 'my-node-active-enter',
                        enterDone: 'my-node-done-enter',
                        exit: 'my-node-exit',
                        exitActive: 'my-node-active-exit',
                        exitDone: 'my-node-done-exit',
                    }}
                    key={location.key}

                >
            <Switch location={location}>
                <Route exact path={"/"}>
                 
                    <div className={"bg-red-500 text-white w-full h-16"}>
                        RED
                    </div>
                </Route>
                <Route exact path={"/purple"}>
                   
                    <div className={"bg-lcnuk-other text-white w-full h-16"}>
                        PURPLE
                    </div>
                </Route>
                <Route exact path={"/blue"}>
                 
                    <div className={"bg-blue-500 text-white w-full h-16"}>
                        BLUE
                    </div>
                </Route>
                <Route exact path={"/yellow"}>
                 
                    <div className={"bg-lcnuk-other text-white w-full h-16"}>
                        YELLOW
                    </div>
                </Route>
                <Route exact path={"/pink"}>
                 
                    <div className={"bg-white text-black w-full h-16"}>
                        PINK
                    </div>
                </Route>
                <Route exact path={"/aqua"}>
                
                    <div className={"bg-black text-white w-full h-16"}>
                        AQUA
                    </div>
                </Route>
                <Route path={'*'}>
                    <div>Not Found</div>
                </Route>
            </Switch>
                </CSSTransition>
            </TransitionGroup>
        </div>
            </div>
        </>
    )
}
export default TransGroup
cannon303
  • 403
  • 2
  • 12

1 Answers1

1

When using CSSTransition for routes, you don't want to use a Switch or a TransitionGroup. You want to put the CSSTransition in each route individually, and then each route will need it's own ref and you need to pass the ref to the nodeRef prop of the CSSTransition node.

Here's a working example I made on Codesandbox:

And here's the block of code that demonstrates this:

///...

interface AppRoute {
  path: string;
  title: string;
  Component: React.ComponentType;
}

const appRoutes: AppRoute[] = [
  { path: "/", title: "Home", Component: HomePage },
  { path: "/page1", title: "Page 1", Component: Page1 },
  { path: "/page2", title: "Page 2", Component: Page2 }
];

///...

////// CONTENT TRANSITION ROUTER
const PageContent = withRouter(({ location }) => {
  let routeRefs: any[] = [];

  const isMatch = useCallback(
    (path: string): boolean => {
      return location.pathname === path ? true : false;
    },
    [location]
  );

  return (
    <>
      {appRoutes.map(({ path, Component }, index) => {
        routeRefs[index] = React.useRef(null);

        return (
          <Route key={index} exact path={path}>
            {() => {
              // Route callback ensures the transitions are loaded correctly
              return (
                <CSSTransition
                  nodeRef={routeRefs[index]}
                  in={isMatch(path)}
                  timeout={300}
                  classNames="fade"
                  unmountOnExit
                  appear
                >
                  <div ref={routeRefs[index]} className="fade">
                    <Component />
                  </div>
                </CSSTransition>
              );
            }}
          </Route>
        );
      })}
    </>
  );
});
Dharman
  • 30,962
  • 25
  • 85
  • 135
Jordan Arldt
  • 346
  • 2
  • 10
  • Perfect thank you!!! – cannon303 Oct 20 '21 at 17:03
  • @cannon303 Of course! Also a small thing to note about my code block. Instead of `return location.pathname === path ? true : false;` you can make it more efficient by doing `return location.pathname === path ?? false;` by using a nullish coalescing operator instead. – Jordan Arldt Oct 21 '21 at 04:13