question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Utilize Suspense to express app init loader

See original GitHub issue

With Concurrent mode getting finalized, I went to try to solve an old problem I have.

The app needs to run a series of init steps before it can do anything viable. Each steps depends on the previous one. This is expressed as nested components. The fairly elaborate animated logo is shown for that process, but it’s being restarted for each step and the experience is not that nice.

I’ve prepared a demo with some experiments: https://codesandbox.io/s/react-suspense-loader-experimental-0ww6i

The first one that’s active initially is what we currently have. The second is what we would like to have, but with less naive coding of decreasing counter.

The last one is my attempt to use Suspense, but I definitely missing something out here, because it behaves very oddly and I cannot seem to figure out why. I wonder if the new useTransition should be used somehow or what’s going on here.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:11

github_iconTop GitHub Comments

1reaction
Eddie-CooRocommented, Oct 31, 2019

Sorry if I wasn’t able to explain correctly what is happening in your example. Let me try one more time. 😅

So, there are two different things to examine,

Firstly, when a component suspends during its mount, none of its effects get called, and neither its state gets persisted. Let’s think about that this way, the useEffect documentation says:

effects run after every completed render

So when a component suspends, nothing gets rendered; therefore, React doesn’t call any of its effects. But it’s not a Problem by itself. It’s a Behavior, and it tells us that when our component suspends, it shouldn’t rely on any of its effects, or ref/state s to un-suspend correctly.

Secondly, When we first let the component to mount before suspending it, for a short amount of time, the fallback doesn’t show up because everything is rendered without suspending (but our component is returning “null” as its children). So this is the order of events, starting with the suspension of the step1 component:

  1. Step1 Component suspends and fallback component gets mounted on the screen.
  2. Step1 Component finishes suspending and renders its children.
  3. Step2 Components render function gets called.
  4. Because the initial state of the component step2 is ‘pending,’ it renders without suspending and returns nothing as it’s children.
  5. So react unmounts the fallback
  6. React mounts the step1 component as well as its children (a.k.a component step2). Now, after committing the virtual DOM, we will see an empty screen. Because step1 renders step2, and step2 renders nothing.
  7. Every passive effect gets called (as well as step2 component useEffect hook callback). and as a result, the state of the step2 component will change to ‘exec.’
  8. Step2 component re-renders duo to the change of the state and this time throws a promise and suspends.
  9. React mounts the fallback component again, and we will see the new percent on the screen

So at one point in time(when we are at event number 6), there will be nothing displayed on the screen, and this will result in flashing of the fallback component for a second

But the order of the events for the example I sent in the previous comment, is different:

  1. Step1 Component suspends and fallback component gets mounted on the screen.
  2. Step1 Component finishes suspending and renders its children.
  3. Step2 Components render function gets called.
  4. Step2 Component suspends during its render.
  5. React forgets everything about the Step2 Component and falls back to the fallback component.

So the fallback component stays mounted on the screen all the time.

0reactions
stale[bot]commented, Feb 6, 2020

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Experimental React: Using Suspense for data fetching
In this article, we'll look at how Suspense works by creating a simple app that fetches data from an API and renders it...
Read more >
Lazy Loading React Components (with react.lazy and suspense)
Firstly, bundling involves aligning our code components in progression and putting them in one javascript chunk that it passes to the browser; ...
Read more >
You definitely should be using Suspense in React — code ...
However, you could start using React Suspense for one huge thing already: lazy loading components via code splitting .
Read more >
Lazy loading in React - LoginRadius Blog
General instructions · We will perform lazy loading with React suspense and without it. · First of all, create the app using npm...
Read more >
How To Handle Async Data Loading, Lazy Loading, and Code ...
With asynchronous code you can also update your application by ... In future versions of React, you'll be able to use Suspense to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found