简体   繁体   中英

Loading indicator is not displaying when user navigates between loaded pages (NextJS, ReactJS)

What do I need:

I want to display a loading indicator, when user navigates between pages. I saw an example https://github.com/zeit/next.js/tree/canary/examples/with-loading and it works for me. In my app I've implemented a similar logic. For an experiment as a loading indicator I just change the color of tag .

try {
  if (isLoading) {
    document.getElementsByTagName('body')[0].style.backgroundColor = 'red'
    console.log('RED')
  }
  else {
    document.getElementsByTagName('body')[0].style.backgroundColor = 'green'
    console.log('GREEN')
  }
}
catch (err) {
}

And I use events like this:

Router.events.on('routeChangeStart', url => {
  setIsLoading(true)
})
Router.events.on('routeChangeComplete', () => setIsLoading(false))
Router.events.on('routeChangeError', () => setIsLoading(false))

What happens:

In a first time, when page is not built yet and not loaded from the server, and user navigates to it, the color is changed and all is fine. But after, when user comes back to the already loaded page, the color of body is not updated.

This code is performed in any case, because I see console.log, but color is not changes.

Interesting thing #1 - if I put 'debugger' before the line of changing the color, then it stops on this line and color updated, even for already loaded pages. As I need.

Interesting thing #2 - If I will use setTimeout for coloring by green, then for already loaded pages, the background will stay green during redirection. After the redirection will be finished, it will became red, and after the timeout it will be again green.

I use:

  • nextjs 9.1.7
  • React 16.12.0
  • Also redux, but I dont think it's important.

It looks like browser does not update DOM while navigation to the already loaded page is performing. Can anyone give me an advice, what could the reason that for already loaded pages I cannot update DOM when user does navigation?

I found a reason of a problem.

How does it work:

Actually, when page is already rendered and loaded by nextjs, the router renders it immediately after the user navigates on it.

Why the problem did happen:

In my example I had two pages. They contained a lot of data (one of them was especially heavy). After the user navigated to the already loaded page, the browser has started the rendering immediately and it took ~2 seconds. Since the rendering in browser was in progress, it was not able to render the loading indicator. And after the rendering was done, the event "routeChangeComplete" was fired and the loading indicator disappeared immediately after the page was loaded.

What to do:

  1. More correct to refactor the page and make it render faster. Then we don't need loading indicator for the render.
  2. A workaround could be the next - when you want to do a redirect, you need to render the loading indicator first. And only after, start the redirection and therefore a render of the page. The simpliest way, just to test it is use a setTimeout, to delay the redirection. But I do not recommend this way.

PS an example in sandbox worked well because pages there a very lightweight, and long loading was emulated through setTimeout which does not block rendering.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM