Refactor data fetching with useEffect to Suspense Resources

Share this video with your friends

Send Tweet

A very common practice in React applications today is to request data when a component is rendered within a useEffect callback. Let's refactor that to Suspense with our new resource factory.

Darren Seet
Darren Seet
~ 5 years ago

Hi Kent,

Thanks for exposing this unstable API. Most trainers will not put their heads on the chopping block to introduce alpha stage APIs. I was working through the code and it returns a warning message in the console.

Warning: App triggered a user-blocking update that suspended.

The fix is to split the update into multiple parts: a user-blocking update to provide immediate feedback, and another update that triggers the bulk of the changes.

Refer to the documentation for useTransition to learn how to implement this pattern.

I think it might be an unstable API change that came out after you created the lesson. But I just want to some advice on whether this fix I am applying is the correct pattern. Based on what I read in the React docs, I think the fix is to wrap the statements in handleSubmit with the startTransition function.

I added the useTransition hook to the App function

  const [startTransition] = React.useTransition({
    timeoutMs: 1000
  });

then I changed handleSubmit to the following

  function handleSubmit(newPokemonName) {
    // 🐨 set the pokemon resource right here
    startTransition(() => {
      setPokemonName(newPokemonName);
      setPokemonResource(createPokemonResource(newPokemonName));
    });
  }

Initially I only place setPokemonResource inside startTransition and setPokemonName out of it. That seem to work, but if I change the timeoutMs to a low value like 30. It triggers the warning again but it appears that if you wrap setPokemonName in startTransition as well, the the value of timeoutMs no longer triggers the warning no matter what value you set it. Is this the correct approach to do this with the useTransistion hook? Thank you for any help in advance.

Kent C. Dodds
Kent C. Dodds(instructor)
~ 5 years ago

Thanks for the detailed message @seetd. Check out lesson #8 😉

Kent C. Dodds
Kent C. Dodds(instructor)
~ 5 years ago

Oh, and I'm not 100% certain whether both calls should appear within startTransition or not. I played around with both. Now I think that putting them in startTransition is correct.

Darren Seet
Darren Seet
~ 5 years ago

Thanks. I just saw the lesson plan and I will most likely get to it later in the later. I just I got too far ahead of myself. But I appreciate you taking the time to reply

Viktor Soroka
Viktor Soroka
~ 5 years ago

As I see when the first request fails as a result of the call to nonexistent pokemon and then making a call to an existent one doesn't clear the error result. Only after the click to the try again button the result will be shown. As I understand this is because the error boundary error state is not getting cleared upon the click to the submit button. What is the best way to reset the error boundary state? For now, I made it work via ref with the call errorBoundary.current && errorBoundary.current.tryAgain();.