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: https://codesandbox.io/s/elegant-star-lp7yjx?file=/src/App.js
App
import React from "react";
import {
Navigate,
Route,
Routes,
NavLink,
useLocation
} from "react-router-dom";
import "./styles.css";
import { SwitchTransition, CSSTransition } from "react-transition-group";
const SubPage1 = () => {
return (
<div>
<h1>SubPage1</h1>
<NavLink to="/2">Go to SubPage2</NavLink>
</div>
);
};
const SubPage2 = () => {
return (
<div>
<h1>SubPage2</h1>
<NavLink to="/1">Go to SubPage1</NavLink>
</div>
);
};
const Page1 = () => {
const location = useLocation();
return (
<MyContextProvider>
<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>
</MyContextProvider>
);
};
const Page2 = () => {
return (
<div>
<h1>Page2</h1>
<NavLink to="/1">Go to Page1</NavLink>
</div>
);
};
const MyContext = React.createContext();
const MyContextProvider = ({ children }) => {
React.useEffect(() => console.log("Context mounting"), []);
return <MyContext.Provider>{children}</MyContext.Provider>;
};
export default function App() {
const location = useLocation();
return (
<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>
);
}
index.js
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { MemoryRouter } from "react-router-dom";
import App from "./App";
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<MemoryRouter>
<App />
</MemoryRouter>
</StrictMode>
);
Am I doing something wrong or is this just not supported?