📣 BREAKING CHANGE ALERT: The version of React in this project works like it does in the recorded videos. However in the future experimental builds of React, the SUSPENSE_CONFIG option to useTransition has been completely removed. Read more about this here: https://github.com/facebook/react/pull/19703

Also, keep in mind that removing SUSPENSE_CONFIG won't work as intended in our example, since we are using React 17. So, if you remove it, useTransition will run without any delay which means it will always show the Suspense fallback.

Along with the previous change, the order of tuple returned by useTransition has also changed. With React 18, the current return value is [isPending, startTransition]. So if you like to use it in your code, do not forget to change the order. For those who are interested with learning the reason behind it, can read more about this here: https://github.com/facebook/react/issues/17276

Here's your reminder that you're learning about experimental software which can change at any moment without notice 😅

Transcript

Kent C. Dodds: 0:00 One of the cool things that React Suspense and Concurrent Mode gives you is the ability to configure how your loading states show up over time. It also has built into it some of the things based on some research from people at Facebook on the React team have done to determine what's the best user experience for users with regard to loading state.

0:23 Here with our useTransition for improving loading states, let me just show you the example that we've got. Here we've got a Pikachu, and then I click on Charizard, you'll notice the input updates, but the loading state doesn't show up until just like a tiny bit after.

0:38 The reason that React does this is because it thinks that, "Hey, if I just wait for a little bit, maybe this asynchronous API request or whatever the asynchronous thing is doing, what if maybe that resolves pretty quickly? If it does, then I don't want to bother showing a loading state."

0:54 This also has some implications as well, depending on where you set the state that triggers the suspending component. Our component suspends when the Pokemon resource is set, but if I set that Pokemon resource inside of my submitHandler, then that's going to be done at the same time that the Pokemon name is set, and we're going to see a slightly different experience.

1:18 If I save that and we'll go to Pikachu, we're going to see that loading state and everything, but now watch the input. If I click on Charizard, it takes a second before the input or the loading state shows up, same if I click on Mew. Still, it takes a second.

1:32 We don't have to worry about that because we're doing this in a useEffect. Our Pokemon name gets updated and then our useEffect fires, and we update our Pokemon resource, but this is something that you want to keep in mind that React and Concurrent Mode are doing.

1:46 This is not a bug. This is an intentional feature of React and Concurrent Mode that it will just wait for a little bit before it decides to render out your fallback here. That works out pretty well. Most of the time, they have some pretty good defaults based on some research, but we know a little bit more about our asynchronous interaction.

2:06 We know that it would probably make more sense to give some sort of indication that we have received your request, and we are processing it right now, but not show the loading screen until maybe four seconds, so that the user isn't just staring at a loading screen the whole time.

2:22 That's what this exercise is all about. I give you some examples of what this API looks like, so you can use the useTransition API. Your job is to use that useTransition API to give a better loading state. Then, we also take some extra credits here to improve that further and even further with some additional APIs.

2:44 I think you'll enjoy this. Go ahead and have a good time. We'll see you on the other side of the exercise.