1. 15
    Avoid this Common Suspense Gotcha in by Reading Data From Components
    4m 3s

Avoid this Common Suspense Gotcha in by Reading Data From Components

Michael Chan
InstructorMichael Chan

Share this video with your friends

Send Tweet
Published 3 years ago
Updated 2 years ago

Suspense can have an unfriendly learning curve.
Components with suspended content need a component boundary.
Resource reads can't happen in the same component as the Suspense and error boundaries components.

When you have your Suspense and error boundary components in place but still get errors about them absence, you probably need to move a read() call into a component.

Instructor: [0:00] Now that we've hoisted our component state up from our Pokemon detail into our application, we can start coordinating it with other state. Let's get some other state. I'd like to get a list of Pokemon that we might be able to select from. Let's duplicate this. Change to initial collection, it'll be a list of our Pokemon.

[0:25] The way that PokéAPI is is that if I don't pass in a number, it'll give me an entire collection of Pokemon. When we save our application, we'll now make this request as soon as the application loads. We can see the shape of this response. It has some Metadata, Account, Next, Previous, because it's paginated, and a Results Array, which has a bunch of Pokemon here.

[0:53] For now, just to hook everything up, we're just going to use Account. Doing that, we'll be able to see a few of the React Suspense gotchas. Here we'll use a div, interpolate out initialCollection.read to get those values from the resource, .count. Save and see what happens. It blew up, but we've got two errors, which is always great in React.

[1:20] We see these two errors that should feel very familiar at this point. We know how to deal with those, so let's just copy and paste what we have up here around our Pokemon component. See that'll get us where we want to go. Format, save, nada. We have the same, exact errors.

[1:47] This might be perplexing because you say, "Well, I have an error boundary. I'm using it here. I also have a Suspense and a fallback, which I'm using here, so what gives?" Something that has caused me the most trouble learning Suspense is these errors when I'm wrapping up my component in error boundary and React Suspense.

[2:07] I can tell you from experience, when you see these errors together and in particular, when you see the one that says, "Visit this URL to learn more about error boundaries," chances are you're trying to call read outside of a component. Whenever we call read, we need to do it inside of a component boundary.

[2:28] Let's cut this code and use a component instead. Pokemon collection, go to the end of our file and define that component. We don't need to take props right now, just return what we had before. Just with that one little change, this will fix everything and make everything work the way it did before.

[2:55] Now that we know how to avoid that Suspense gotcha, I thought it would be nice to spit out a list of some of the Pokemon we have. Let's refresh this, close our console and see where that lives.

[3:11] We have a property on our response called results and change that here. Because it's an array, we can call math on it. For each of those Pokemon, return a list item with the Pokemon name. Format, save and we have a nice little list.

[3:33] We also got an error. This should be common to you if you are familiar with React. Every one of this list elements needs a key prop. Let's add that on. Ideally, we would be able to use a Pokemon ID, but we don't have one. Fortunately, we know that Pokemon names are unique so we can use that as our unique key. Save and the error goes away, but our list remains.

Darren Seet
Darren Seet
~ 3 years ago

I could not replicate the error that was shown in the video. It appears that this <div>{initialCollection.read().count}</div> works with no issues.

It might be due to the experimental state of Suspense. The following are my versions (although the version number might make no sense)

"react": "^0.0.0-experimental-b53ea6ca0",
"react-dom": "^0.0.0-experimental-b53ea6ca0",
Stephen James
Stephen James
~ 3 years ago

I also did not see that error. I am using the same version - I would assume the value after experimental is the commit hash for this version.

Michael Chan
Michael Chaninstructor
~ 3 years ago

seetd, Stephen James, and all others who were not able to reproduce the error,

I am very sorry for the inconvenience. Here's what went wrong:

Before publishing the course, I changed src/index.js to use a dynamic component import so that the let lesson = "complete"; could be on its own line.

In order to make the dynamic import work, I had to wrap the <Lesson /> in <Suspense /> which consequently did the work of catching suspended state of initialCollection.

I've fixed the mistake with this diff: https://github.com/chantastic/react-suspense-course/commit/dbd7e02c7033750a65e7c6ea457c64c3e8029e16.

Again, very sorry for the careless last minute change.