React.Suspense doesn’t work with Gatsby (yet)
Sung M. Kim

Sung M. Kim @dance2die

About: Exploring the world of TypeScript, React & Node

Location:
NYC - the Big 🍎
Joined:
Aug 5, 2017

React.Suspense doesn’t work with Gatsby (yet)

Publish Date: Aug 1 '19
35 8

          Photo by Егор Камелев on Unsplash

          (Image chosen cuz it’s a suspense-invoking cute lil’ creature 😅)

I was loading components dynamically on Gatsby using React.lazy, which required to use React.Suspense.

But then I got the following message while building the site.

          Actually I found out while deploying it on Netlify first 😅 (then ran gatsby build locally)

WebpackError: Invariant Violation: Minified React error #294; visit https://reactjs.org/docs/error-decoder.html?invariant=294 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

Fonts look broken on local machine too by the way

The error message points you to https://reactjs.org/docs/error-decoder.html?invariant=294, which shows that

ReactDOMServer does not yet support Suspense.

Nice clear message (no sarcasm intended).

Gatsby uses ReactDOMServer in the build process thus the error occurred.

Fixing the Offending Code

Below is the offending code using React.lazy causing the issue.

Don’t do this, yet as it’s not supported!

Components are loaded “lazily” on line #6, which caused React.Suspense wrap in the return statement at the bottom.

          Lines #28 ~ #30

So to remove Suspense, get rid of React.lazy and replace it with a regular dynamic import(), and return a default module.

We need to keep the components loaded in a state, so let’s use useState and load it in the useEffect hook.

          If you want to use Class Components, refer to case #1 of my other post, Loading React Components Dynamically on Demand, which was written when Hooks weren’t available

This now builds 🙂

allDirectory is loaded via a static GraphQL query, and when the directories are loaded, it causes the useEffect to render.

And loadComponents (aptly named, right? 😉) loads all components dynamically, and saves it to components state, which is used within return statement to render.

Regarding key={Component}, I was too “lazy” to come up with a unique key so used an object instead.

Parting Words

As the title shows, I just wanted to point out that Suspense isn’t working with Gatsby, yet.

But I ended up fixing the issue and wrote more soon after.

I am going to keep the “fix” part short as it’s already written about in the previous posts already.

If you have a trouble with converting it into using Function Components with hooks, let me know~

The post React.Suspense doesn’t work with Gatsby (yet) appeared first on Sung's Technical Blog.

Comments 8 total

  • Ben Halpern
    Ben HalpernAug 1, 2019

    WHAT IS UP WITH ALL THESE SPIDERS LATELY ON DEV? Is it a trend or something? 😧

    • Sung M. Kim
      Sung M. KimAug 1, 2019

      THEY 🕷 are your friendly neighbors 😉

      With seriousness, if anyone find the Spider image unbearable, let me know.

  • LuisPa
    LuisPaAug 1, 2019

    Great post!

    I've been using React Loadable for lazy loading in my react apps.

    I guess this is a good start to send a PR to add this feature natively!

    • Sung M. Kim
      Sung M. KimOct 18, 2019

      Sorry for the late reply and thank you~.

      Can React Loadable be used for SSR? (Gatsby/next, etc)?

      • Yordan
        YordanNov 4, 2019

        Yes! And it works extremely well!

        • Sung M. Kim
          Sung M. KimNov 4, 2019

          Thanks, Jordan. 👍

          I will give it a try for the next project 🙂

  • Georgina Grey
    Georgina GreyOct 18, 2019

    Thank you. You probably saved me a few hours of debugging :O

    • Sung M. Kim
      Sung M. KimOct 18, 2019

      You're welcome and I should probably log problems I had more often :)

Add comment