Skip to content

Instantly share code, notes, and snippets.

@perlow
Last active December 29, 2023 11:10
Show Gist options
  • Save perlow/bb7612b25f37667be964f1a1aba42780 to your computer and use it in GitHub Desktop.
Save perlow/bb7612b25f37667be964f1a1aba42780 to your computer and use it in GitHub Desktop.
import { useLayoutEffect, useRef, useState, useTransition } from 'react'
import { Router } from 'react-router-dom'
import { BrowserHistory, createBrowserHistory, Update } from 'history'
export interface BrowserRouterProps {
basename?: string
children?: React.ReactNode
window?: Window
}
export function SuspenseRouter({ basename, children, window }: BrowserRouterProps) {
let historyRef = useRef<BrowserHistory>()
const [isPending, startTransition] = useTransition()
if (historyRef.current == null) {
//const history = createBrowserHistory(startTransition, { window });
historyRef.current = createBrowserHistory({ window })
}
let history = historyRef.current
let [state, setState] = useState({
action: history.action,
location: history.location,
})
function setStateAsync(update: Update) {
startTransition(() => {
setState(update)
})
}
useLayoutEffect(() => history.listen(setStateAsync), [history])
return (
<Router
basename={basename}
children={children}
location={state.location}
navigationType={state.action}
navigator={history}
/>
)
}
export default SuspenseRouter
@hoangtrucit
Copy link

hi @perlow, how to use SuspenseRouter in App.tsx. Thanks

@Haraldson
Copy link

@perlow Do you have a usage example? Maybe as a separate file in this gist?

@neriyashul
Copy link

Here is an example:

// App.tsx

import React, { Suspense, lazy } from 'react';
import { Routes, Route } from 'react-router-dom';
import SuspenseRouter from "./SuspenseRouter";

const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));

const App = () => (
  <SuspenseRouter window={window}>
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  </SuspenseRouter>
);
export default App;

@firatoezcan
Copy link

firatoezcan commented Mar 23, 2023

How would one extend this to show an indicator, that the route is currently waiting for something? I'm not super familiar with the new concurrent features sadly to figure this out myself

@Johnny159
Copy link

fallback does not show...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment