1

At this point if someone can figure this out I would be willing to pay some money.

My question pertains to using React Router and the new React 18's useTransitions. At the current stage, lazy loading is implemented using React.lazy and React.Suspense around the routes with the fallback being some React component you choose. As people have noticed, there is 'flickering' etc. So now there is useTransitions. Does anyone have an implementation using these to make it so you can stay on the current rendered page until the next page is ready to load.

I have seen this post: React lazy/Suspens + React Router dont change route until component is fetched

But it does not seem to work. I'm using react-router v5 and react v18.2. I have seen many people ask something similar, but if someone could share their implementation, I believe it would benefit more than myself.

I appreciate your time to view this. Thank you.

bearsworth
  • 77
  • 1
  • 2
  • 11
  • @bearsworth, have you tried wrapping `navigate` inside `startTransition`? Ref: https://reactjs.org/docs/hooks-reference.html#usetransition. I'm not too sure about that so I won't post that as an answer. – Matthew Kwong Jul 11 '22 at 03:05
  • @MatthewKwong I was hoping there would be a solution I could apply to all my routes. That works if you want to go from 1 page to another but there is something out there that can do it all, I just don't know how people are implementing it. Thanks for the response though. – bearsworth Jul 11 '22 at 03:29
  • @Four I wish I could, but that would probably take me a while to rewrite what I have done. As Matthew you said, yeah common man :(. – bearsworth Jul 11 '22 at 03:30
  • @bearsworth, At least there is some good news, from React Router doc: "React Router v6 uses the `useTransition` hook at the root of your component hierarchy.". I guess your best bet is to upgrade to v6, since v5 will properly not receive any further updates anymore. – Matthew Kwong Jul 11 '22 at 03:36
  • @MatthewKwong yeah I was using v5. I actually almost finished moving over to v6 in the past hour or so to test if it works. Thanks for the response and help. – bearsworth Jul 11 '22 at 03:40
  • @MatthewKwong Well it looks like good news. You were right in that it is automatic. I guess that closes it out? Based on testing I sometimes see a slight flicker, but overall, it appears to be working. I guess this is a wrap. v6 automatically does have it working. – bearsworth Jul 11 '22 at 03:46
  • After further testing, it appears lazy loaded components will show the fallback. I guess I'm still having the issue even after upgrading. I'm guessing there is something I have to program to make it work where I stay on the page before rendering. This question remains unanswered. – bearsworth Jul 12 '22 at 09:21

3 Answers3

2

You can try with route-level-code-split for that you need to create custom FallbackProvider and utils. Which helps you store your current component until the next page is not loaded yet.

Here is the example Demo

Source code Link

Asif vora
  • 3,163
  • 3
  • 15
  • 31
  • 1
    This is very interesting. I read part of the repo and this approach seems like it could work. My only concerns are that it might be this: "The above approach is not well tested though. I have only tested a fake modal. And if you have to include very complex UI components (like popovers and portals) , I wouldn't garuantee this works. Feel free to open an issue then." It gives me some pause, but gives me some idea about how to work with this. – bearsworth Jul 12 '22 at 09:27
1

My suggestion for React v18 + React-Router-Dom v6 + Webpack would be to use @loadable/component

https://www.npmjs.com/package/@loadable/component

https://github.com/gregberge/loadable-components

Replace this:

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

const Home = lazy(() => import(/* webpackChunkName: "routes-home" */ './routes/Home'))

export default function App(){
  return (
   <Suspense fallback={<Loading />}>
    <Routes>
      <Route path="/routes/home" element={<Home />} />
    </Routes>
   <Suspense />
  )
}

With this:

import loadable from '@loadable/component'

const Home = loadable(() => import(/* webpackChunkName: "routes-home" */ './routes/home'))

export default function App(){
  return (
    <Routes>
      <Route path="/routes/home" element={<Home />} />
    </Routes>
  )
}

P.S. /* webpackChunkName: "routes-home" */ is optional

James Prentice
  • 134
  • 1
  • 6