DEV Community

Rodrigo Pombo
Rodrigo Pombo

Posted on

About React Suspense and Concurrent Mode

The next big things on the React roadmap are Concurrent Mode and Suspense.
They are related and complement each other, so people sometimes mix them up. But they represent very different concepts.

Concurrent Mode

Signs for priority and economy lanes

To understand Concurrent Mode think about priorities.

Without Concurrent Mode, when React starts rendering something it keeps rendering it until it finishes.

With Concurrent Mode, React will keep an eye on other things that need to be done, and if there's something with a higher priority it will pause what's rendering and let the other thing finish first. That "other thing" could be:

  • something the browser needs to do
  • another update that React needs to render
  • any other task from other libraries or the app's code
import {
  useState,
  takeYourTimeToRenderThisUpdate,
  iNeedThisUpdateAsSoonAsPossible
} from "fictitious-react";

function SlowButLowPriorityComponent() {
  const [someData, changeData] = useState(0);
  return (
    <div>
      <BigComponentThatTakesVeryLongToRender someProp={someData} />
      <button
        onClick={() => {
          takeYourTimeToRenderThisUpdate(() =>
            changeData(prevData => prevData + 1)
          );
        }}
      >
        Expensive but low priority change
      </button>
    </div>
  );
}

function FastAndHighPriorityComponent() {
  const [someData, changeData] = useState(0);
  return (
    <div>
      <SmallComponentThatRendersFast someProp={someData} />
      <button
        onClick={() => {
          iNeedThisUpdateAsSoonAsPossible(() =>
            changeData(prevData => prevData + 1)
          );
        }}
      >
        Fast and high priority change
      </button>
    </div>
  );
}

function App() {
  return (
    <div>
      <SlowButLowPriorityComponent />
      <FastAndHighPriorityComponent />
    </div>
  );
}

// If the user clicks first the SlowButLowPriorityComponent button
// and then the FastAndHighPriorityComponent button
// React will stop rendering SlowButLowPriorityComponent
// and finish rendering FastAndHighPriorityComponent (with its new state) first
// only then it will continue with the SlowButLowPriorityComponent update
Enter fullscreen mode Exit fullscreen mode

You won't need to explicitly set the priority for each update, if you don't React will try to guess the right one.

Suspense

Flight information display

For Suspense think about waiting.

Without Suspense, if your component needs to wait for any dependency (for example, if it depends on some data that needs to fetch from a server) you need to add some state to keep track of the pending dependency, render something while the dependency is pending, and update the state when the dependency is ready.

With Suspense, your component will be able to tell React "Hey React, I don't have all the things I need to be rendered, but I'll let you know when you can try to render me again". Your component won't need to keep extra state or to decide what to render while waiting.

import {
  dontRenderMeUntilThisIsReady,
  Suspense as TryRenderTheseChildren
} from "fictitious-react";
import getMyDependency from "fictitious-dependency-fetcher";

function ComponentThatDependsOnSomething(props) {
  const dependency = dontRenderMeUntilThisIsReady(
    getMyDependency(props.dependencyId)
  );
  return <h1>{dependency.data}</h1>;
}

function App(props) {
  return (
    <TryRenderTheseChildren andIfTheyAreNotReadyRenderThis={<ImTheFallback />}>
      <ComponentThatDependsOnSomething dependencyId={1} />
      <ComponentThatDependsOnSomething dependencyId={2} />
    </TryRenderTheseChildren>
  );
}
Enter fullscreen mode Exit fullscreen mode

And Now for Something Completely Different

Escher drawings at the airport

I'm at the Amsterdam airport, after #ReactAmsterdam, waiting for my delayed flight, looking at these drawings by Escher, and writing a post that makes an analogy of me writing a post while waiting for my delayed flight.

Top comments (7)

Collapse
 
pulljosh profile image
Josh Pullen

Love the verbose pseudocode as a way of explaining what's happening. This is the first time I've understood either of the features, and it feels so natural. Excellent article! 👍

Collapse
 
blnkspace profile image
AVI

Second that

Collapse
 
miteshdv profile image
Mitesh Dave • Edited

So what's differnce between react fiber nd concurrent mode? Can you please tell me

Collapse
 
pomber profile image
Rodrigo Pombo • Edited

React Fiber refers to the new algorithm and data structures that React uses internally (since React 16.0.0). The old algorithm made implementing Concurrent Mode very difficult.

The old algorithm, sometimes called Stack Reconciliation, rendered the elements recursively. So it wasn't easy to stop it after it started rendering an element tree.

function render(element) {
  rememberToCommitToTheDom(element)

  const children = getChildren(element);
  children.forEach(child =>
    render(child)
  )
}
Enter fullscreen mode Exit fullscreen mode

The new algorithm renders the element tree inside a while, so it's easier to pause and re-start later.

let nextElement

function render(element) {
  nextElement = element
  workLoop()
}

function workLoop() {
  while (nextElement && !shouldYield()) {
    rememberToCommitToTheDom(nextElement)
    nextElement = getNextElement(nextElement)
  }
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
kambleaa007 profile image
Ashish Kamble

Introducing Concurrent Mode (Experimental) and coming in next year, why its old algorithm, i dont understand

Collapse
 
huykonofficial profile image
Huy Kon

I don't understand what were you describe of this article! It is very difficult to understand about Concurrent Mode

Collapse
 
aromanarguello profile image
aromanarguello

Such a great write up!