CSS transition , react-transition-group and React.findDOMnode deprecation

402 Views Asked by At

I encountered a Warning relative to the findDOMnode deprecation when trying to use react routing in combination with react-transition-group, the warning stated:

index.js:1 Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of Transition which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-find-node

The above warning refers to the following code:

<Route  key={path} path={path} exact>

  
{({match})=>(

  <CSSTransition
 
  in={match!=null}
  timeout={300}
  classNames="page"
  unmountOnExit
  mountOnEnter
  
  >

    <div  className="page">
    
      <Component />
    </div>
  </CSSTransition>  

 )}

  </Route>)  

My first attempt of getting rid of that warning was to make use of useRef as suggested:

const nodeRef = useRef(null);

passing nodeRef as ref prop of the CSStransation element but the warning was still showing up.

For some reason I could only get rid of the warning by passing the triggering event that I was also using in the 'in' prop of the CSStransition element, like showed here below:

 <Route  key={path} path={path} exact>

  
{({match})=>(

  <CSSTransition
  
  ref={nodeRef}
  in={match!=null}
  timeout={300}
  classNames="page"
  unmountOnExit
  mountOnEnter
  key={match!=null}    <------------ Adding this removed the warning
  >

    <div  className="page">
    
      <Component />
    </div>
  </CSSTransition>  

 )}

  </Route>) 

Everything work smoothly now but I cant really undestand why, and even if I remove the the ref from the CSStransition element I dont get any warning anymore.

Does anybody undestand why this is actually happening?

1

There are 1 best solutions below

0
On

I spent a while trying to figure this out as well, and I finally got it! You need to use the nodeRef prop in the CSSTransition for each route individually. Each route gets its own ref, and that ref needs to be assigned to the nodeRef accordingly. I was able to get this working by using an array of refs, mapping each route and assigning the refs to the current index.

Take a look at this working example I made:

And here's the block of code that is going to be the most helpful:

////// 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>
        );
      })}
    </>
  );
});