React Concurrent

+

React Suspense

Omar Jbara

Fullstack developper @ Cap Collectif

What is React Concurrent

No, seriously, what is it?

A mode that change React's rendering techniques

Interruptible Rendering

Without React Concurrent

  1. Update some state
  2. React update the VDOM
  3. React commit changes and perform DOM manipulations
  4. The browser has to refresh / paint it's layout

All this stuff is blocking. When React renders, it can not interrupt it's work 

Interruptible Rendering

With React Concurrent

  1. Update some state
  2. Let the browser paint the update
  3. Update changes in-memory
  4. When rendering phase is finished, React commits the changes and updates the DOM accordingly

With this approach, React can prioritize updates and avoid stuterrings

Intentional Loading Sequences

  • Avoid jarring UX by controlling when a UI is considered in a "good state" for display
  • Gives developpers controls on how to orchestrate these loadings sequences

Concurrent mode

(KISS bby)

  • Enable working on several state updates concurrent​ly
    • React can prioritize some updates and decides which ones are more important than others

And what about Suspense?

Suspense is a mechanism

  • Says that a component is not ready to render

No seriously, that's it

Well, I may have lied to you a bit....

What is exactly Suspense?

  • It is a mechanism for data fetching libraries

  • It is a way to read any asynchronous data from a component
  • It allows developpers to orchestrate loading UIs and have a fine-grained control over them

What is exactly not Suspense?

  • It is not a data fetching implementation

  • It does not couple data fetching to the view layer

Suspense (and Concurrent) are experimentals

You may expect some BCs

Suspense primitives

The Suspense Component

<Suspense fallback={<Loader />}>
  <PostList /> 
</Suspense>

Display a <Loader/> when <PostList/> is fetching data

Suspense primitives

The SuspenseList Component

<SuspenseList revealOrder="forwards" tail="collapsed">
  <Suspense fallback={'Loading...'}>
    <ProfilePicture id={1} />
  </Suspense>
  <Suspense fallback={'Loading...'}>
    <ProfilePicture id={2} />
  </Suspense>
  <Suspense fallback={'Loading...'}>
    <ProfilePicture id={3} />
  </Suspense>
  ...
</SuspenseList>

Orchestrate loadings of <ProfilePicture/> components so that they appear from top to bottom

Suspense primitives

The useTransition hook

const SUSPENSE_CONFIG = {timeoutMs: 200 };

function App() {
  const [resource, setResource] = useState(initialResource);
  const [startTransition, isPending] = useTransition(SUSPENSE_CONFIG);
  return (
    <>
      <button
        disabled={isPending}
        onClick={() => {
          startTransition(() => {
            const nextUserId = getNextId(resource.userId);
            setResource(fetchProfileData(nextUserId));
          });
        }}
      >
        Next
      </button>
      {isPending ? " Loading..." : null}
      <Suspense fallback={<Spinner />}>
        <ProfilePage resource={resource} />
      </Suspense>
    </>
  );
}

Allows to tells React that some user-action will transition to a new state that will cause the component to suspend. This can only be done thanks to Concurrent Mode

React Concurrent

  • Allows React to interrupt it's render to do more important stuff and getting back to where it was
  • Enables new UI/UX mechanics (loading sequences, loading UIs orchestration...)
  • Changes how React's internal rendering is done

React Suspense

  • Allows to suspend any components that asks asynchronous data
  • Allows a more fine-grained control of loading fallbacks on a per-component basis
  • Extract cumbersome loading states logic from the component to the parent

Early adopters:

We are not all Facebook

Thanks you

References

Made with Slides.com