Skip to content

Instantly share code, notes, and snippets.

@ozkary
Last active March 17, 2023 15:21
Show Gist options
  • Save ozkary/f01785e0ee46935d02f5cff9b3d31df2 to your computer and use it in GitHub Desktop.
Save ozkary/f01785e0ee46935d02f5cff9b3d31df2 to your computer and use it in GitHub Desktop.
React Routing with Suspense approach to avoid re-rendering of child components. - See https://www.ozkary.com/2023/02/react-suspense-fallback-keeps-rendering.html
/*
Lazy loading component with Suspense support
*/
import React, { Suspense } from 'react';
import Loading from './Loading';
const App = (): JSX.Element => {
// lazy load the containers. This should create different chunk file
const Home = lazy(()=> import('./containers/Home'));
const Analytics = lazy(()=> import('./containers/Analytics'));
const Admin = lazy(()=> import('./containers/Admin'));
return (
<Layout className="app">
<Suspense fallback={<Loading />}>
<Routes>
<Route key={'home'} path={'/'} element={ <Home/> }/>
<Route key={'analytics'} path={'/analytics'} element={<Analytics/>}/>
<Route key={'admin'} path={'/admin'} element={<Admin/>}/>
</Routes>
</Suspense>
</ErrorBoundary>
</Layout>
);
};
export default App;
/*
Adding a router component instead of declaring the routes
*/
import React, { Suspense } from 'react';
import AppRouter from './router';
import Loading from './Loading';
const App = (): JSX.Element => {
return (
<Layout className="app">
<Suspense fallback={<Loading />}>
<AppRouter />
</Suspense>
</Layout>
);
};
export default App;
/**
* Component to creates the route information (custom interface) with lazy load containers as element
**/
const getRoutes = () : routeInfo[] => {
const pageRoutes = routes.reduce((result: routeInfo[], routeItem) => {
const elm = lazy(() => import(`../containers/${cmp}`));
const routes = routeItem.path?.map((path) => {
return {
key: routeItem.component,
path: path,
elm: elm
} as routeInfo
});
result.push(...routes);
return result;
},[]);
return pageRoutes;
}
/*
This component has a re-rendering problem. See router with state for the solution
*/
const Router = (): JSX.Element => {
const pageRoutes = getRoutes();
return (
<Routes>
{pageRoutes.map((routeItem) => (
<Route
key={routeItem.key}
path={routeItem.path}
element={
<routeItem.elm />
}
/>
))}
</Routes>
);
};
export default (Router);
/*
Routing with state management
*/
const Router = (): JSX.Element => {
const [pageRoutes, setPageRoutes] = useState([] as routeInfo[]);
// initialize the route dependencies
useEffect(() => {
if (!pageRoutes || pageRoutes?.length < 1) {
const list = getRoutes();
setPageRoutes(list);
}
},[pageRoutes]);
if (!pageRoutes || pageRoutes.length < 1) {
return (<></>);
}
return (
<Routes>
{pageRoutes.map((routeItem) => (
<Route
key={routeItem.key}
path={routeItem.path}
element={
<routeItem.elm />
}
/>
))}
</Routes>
);
};
export default memo(Router);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment