React Suspense: How to use it to improve user experiences in concurrent mode

React Suspense is a useful way to suspend rendering components. It is still fairly new, yet provides lots of amazing benefits. Therefore, you must join us today to discover it!

Firstly, let’s have a look at some key terms:

Some Key meanings

User Experience

UX or User Experience is basically how users interact with your app. What’s more, it is shown through our emotions and attitudes towards a particular product or service. As a result, creating the best User-centered UX means better profits and sales.

Suspense

Suspense is a mechanism for data fetching libraries. To clarify, it communicates with React to notify when a component is ready to be read or not, aka Suspending. At that time, React can wait and then update UI (User Interface).

As a matter of fact, React aims at making Suspense the primary way for reading synched data from components in very near future. Therefore, the sooner you know about it, the better!

Attention!

Since Suspense is rather new, many mistake it with other components and think of its non-existent use. Following are some most common misreadings:

  1. Firstly, it doesn’t integrate data fetching to the view layer. Simply put, although it helps arrange and organize UI loading states, Suspense cannot connect React components with your network effectively.
  2. In addition, it is not a ‘ready-to-use’ client. Yes, you can use any libraries that Suspense integrated ( new Relay APIs for instance) but replacing it with Relay is never the case!
  3. Lastly, it is not a data fetching application. To explain, it cannot assume the exact types of data format, library or transport that you are using. 

Concurrent Mode

Concurrent Mode is actually experimental and is not an official component of React yet. It offers a set of features to make React apps stay responsive as well as smoothly adjust to your device in terms of network speed and compatibility. Don’t worry because it’s new, Concurrent Mode will slowly become a promising component soon!

react suspense 1
Example of Concurrent Mode.

There you go, above are important points you must remember! ‘What can React Suspense do for my app’ you may ask? Well, let’s move on to the next part:

Why React Suspense?

The first benefit is that data fetching libraries can integrate with React deeply thanks to Suspense. Indeed, it will create a very natural environment for you to smoothly use. Furthermore, you can arrange the designed loading states in your own way. However, the way data is fetched is still unclear. Regardless, you still have a fairly good amount of control of your app’s visual. And last but not least, you can avoid race condition. In other words, Suspense makes the data reading process easier and more logical. 

 While React Suspense can waits for images, scripts or asynchronous work in general, our article today will mainly focus on its use in Data Fetching.

Suspense for Data Fetching

Fetch-on-render (use Suspense)

React has named this access because only after the component has rendered, it will start fetching. Consequently, it leads to a minor issue that you’ll find later. Let’s have a look at this example:

const App = () => {
  const [todos, setTodos] = useState(null)

  useEffect(() => {

    fetchTodos().then(todos => setTodos(todos)

  }, [])

  if (!todos) return <p>loading todos…</p>

  return (

    <div>

      <Todos data={todos} />

      <Tasks /> // this makes its own request too

    </div>

  )

}

Note that when  <Tasks /> fetches its own data from the API, it will wait until fetchTodos() resolves. Yet, if that process lasts for x seconds, <Tasks /> will have to wait the same x seconds to fetch the data instead of having 2 processes run at the same time. This is called the ‘waterfall’ effect, the one that we mentioned above. Though it is very common, most users will ask for expert help since it will expand when products grow.   

Some good examples are the useEffect Hook or componentDidMount method.

// In a function component:
useEffect(() => {

  fetchSomething();

}, []);
// Or, in a class component:
componentDidMount() {
  fetchSomething();
}
There are 3 data fetching approaches!

Fetch-then-render

This is the only approach that is not supported by React Suspense. Still, it serves the purpose of  preventing the ‘waterfall’ issue. For that reason, Fetch-then-render is still listed as one of the ways to fetch data. Consider this example:

const promise = fetchData() //

const App = () => {

Then

  const [todos, setTodos] = useState(null)

  const [tasks, setTasks] = useState(null)

  useEffect(() => {

    promise().then(data => {

      setTodos(data.todos)

      setTasks(data.tasks)

    }

  }, [])

  if (!todos) return <p>loading todos…</p>

  return (

    <div>

      <Todos data={todos} />

      <Tasks data={tasks} />

    </div>

  )

}

When compared to the previous approach, <Task /> does not trigger its own async request. Instead, it will get the needed data from the parent App component.

Although this case solves the ‘waterfall’ issue, it leads to another problem. We need to wait after post fetching if we want to render profile details.

Render-as-you-fetch (use Suspense)

Needless to say, this is the key advantage that Suspense offers! All of the above issues will be prevented with this approach. Have a look at this example:

const data = fetchData() //

const App = () => (

  <>

  <Suspense fallback={<p>loading todos…</p>}>

    <Todos />

  </Suspense>

  <Suspense fallback={<p>loading tasks…</p>}>

    <Tasks />

  </Suspense>

  </>

)

const Todos = () => {

  const todos = data.todos.read()

  // code to map and render todos

}

const Tasks = () => {

  const tasks = data.tasks.read()

  // code to map and render tasks

}

With an increasing amount of data streams in, React will constantly retry rendering. What’s more, the following will always progress deeper. As a result, no component needs to wait for the other. After all, the system will run more effectively than 2 other approaches.

Quick information for building the app via Suspense

#1. Api

  • wrapPromise.js: directly communicates with Suspense. In fact, every library author spends most of their time on this element.
  • endpoints.js: makes modules in the same app detect and use each other.

#2. Components

  • index.jsx: will be first created because it is the beginning point of our app. We will have to set up our React app to the DOM.
  • App.jsx
  • CompletedTodos.jsx: can render the whole list of completed todo items.
  • PendingTodos.jsx

Need help?

If those terms are difficult to understand, whether you are a starter or have basic knowledge, you can always contact us for the ultimate results.

arrowhitech
A leading IT outsourcing act in Vietnam!

Founded in 2007, ArrowHitech JSC is one of the leading IT outsourcing companies in Vietnam. We have worked with over 1,000 customers worldwide and completed more than 10,000 projects. Based in an Asian country, we provide effective services at a very low cost.

We value every customer, treat them like family and build relationships on trust. For that reason, we are confident that we can help YOU operate your online stores and deliver the best solutions at an affordable cost. For reference, check out our ReactJS Development services right now – we welcome customers all the time!

Ending

That is it for today. We hope that you have learned something new and useful about React Suspense to make some changes in your program. Thank you for joining us today, and ArrowHitech wishes you the best of good luck and success!

We’d love to hear from you at:

Tags

Share