Home > database >  Context provider is unmounting when using React Transition Group with nested routes
Context provider is unmounting when using React Transition Group with nested routes

Time:11-05

I have an application with nested routes and am hoping to use React Transition Group to transition between the routes, both top level and nested.

My challenge is that I have a context provider wrapping the nested routes. That context provider is unmounting when the page transitions between nested routes, causing the provider to lose state. Without the transitions, the context provider does not unmount and thus state is preserved.

I've implemented a simplified example in a code sandbox: Edit context-provider-is-unmounting-when-using-react-transition-group-with-nested-rou

Issue

The MyContextProvider is remounted even when descendent routes change.

This is caused by the root CSSTransition component using a React key coupled to the current location's key. The key changes when the descendent route changes, and when React keys change then that entire sub-ReactTree is remounted.

function App() {
  const location = useLocation();
  return (
    <SwitchTransition>
      <CSSTransition
        key={location.key} // <-- React key change remounts subtree
        classNames="right-to-left"
        timeout={200}
      >
        <Routes>
          <Route path="/1/*" element={<Page1 />} />
          <Route path="/2/*" element={<Page2 />} />
          <Route path="*" element={<Navigate to="/1" />} />
        </Routes>
      </CSSTransition>
    </SwitchTransition>
  );
}

A solution for this is to promote the MyContextProvider higher in the ReactTree such that it remains mounted even while routes change. Wrap the SwitchTransition component with the MyContextProvider and remove MyContextProvider from the Page1 component.

function App() {
  const location = useLocation();
  return (
    <MyContextProvider>
      <SwitchTransition>
        <CSSTransition
          key={location.key}
          classNames="right-to-left"
          timeout={200}
        >
          <Routes>
            <Route path="/1/*" element={<Page1 />} />
            <Route path="/2/*" element={<Page2 />} />
            <Route path="*" element={<Navigate to="/1" />} />
          </Routes>
        </CSSTransition>
      </SwitchTransition>
    </MyContextProvider>
  );
}

Page1

const Page1 = () => {
  const location = useLocation();
  return (
    <>
      <h1>Page1</h1>
      <NavLink to="/2">Go to Page2</NavLink>
      <Routes location={location}>
        <Route path="/1" element={<SubPage1 />} />
        <Route path="/2" element={<SubPage2 />} />
        <Route path="*" element={<Navigate to="1" />} />
      </Routes>
    </>
  );
};

Edit context-provider-is-unmounting-when-using-react-transition-group-with-nested-rou

  • Related