惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
K
Kaspersky official blog
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog
aimingoo的专栏
aimingoo的专栏
M
MIT News - Artificial intelligence
小众软件
小众软件
云风的 BLOG
云风的 BLOG
腾讯CDC
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Hugging Face - Blog
Hugging Face - Blog
S
SegmentFault 最新的问题
Stack Overflow Blog
Stack Overflow Blog
量子位
S
Secure Thoughts
G
GRAHAM CLULEY
C
CXSECURITY Database RSS Feed - CXSecurity.com
人人都是产品经理
人人都是产品经理
雷峰网
雷峰网
T
Threat Research - Cisco Blogs
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cisco Talos Blog
Cisco Talos Blog
G
Google Developers Blog
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
有赞技术团队
有赞技术团队
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Martin Fowler
Martin Fowler
The GitHub Blog
The GitHub Blog
Google DeepMind News
Google DeepMind News
C
Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园 - 聂微东
宝玉的分享
宝玉的分享
H
Hackread – Cybersecurity News, Data Breaches, AI and More
N
Netflix TechBlog - Medium
Forbes - Security
Forbes - Security
Engineering at Meta
Engineering at Meta
S
Security Affairs
Help Net Security
Help Net Security
博客园 - 三生石上(FineUI控件)
AWS News Blog
AWS News Blog
博客园 - 叶小钗
Recent Commits to openclaw:main
Recent Commits to openclaw:main
V2EX - 技术
V2EX - 技术
Hacker News: Ask HN
Hacker News: Ask HN
Project Zero
Project Zero
H
Heimdal Security Blog
W
WeLiveSecurity
C
Check Point Blog

Maxime Heckel's Blog

On Rendering the Sky, Sunsets, and Planets - The Blog of Maxime Heckel Shades of Halftone - The Blog of Maxime Heckel Field Guide to TSL and WebGPU - The Blog of Maxime Heckel On Shaping Light: Real-Time Volumetric Lighting with Post-Processing and Raymarching for the Web - The Blog of Maxime Heckel Speaking at Figma Config 2025 - The Blog of Maxime Heckel Post-Processing Shaders as a Creative Medium - The Blog of Maxime Heckel On Crafting Painterly Shaders - The Blog of Maxime Heckel The Art of Dithering and Retro Shading for the Web - The Blog of Maxime Heckel Moebius-style post-processing and other stylized shaders - The Blog of Maxime Heckel Shining a light on Caustics with Shaders and React Three Fiber - The Blog of Maxime Heckel Real-time dreamy Cloudscapes with Volumetric Raymarching - The Blog of Maxime Heckel Painting with Math: A Gentle Study of Raymarching - The Blog of Maxime Heckel Building a magical AI-powered semantic search from scratch - The Blog of Maxime Heckel Beautiful and mind-bending effects with WebGL Render Targets - The Blog of Maxime Heckel Refraction, dispersion, and other shader light effects - The Blog of Maxime Heckel The magical world of Particles with React Three Fiber and Shaders - The Blog of Maxime Heckel The Study of Shaders with React Three Fiber - The Blog of Maxime Heckel Building a Design System from scratch - The Blog of Maxime Heckel Everything about Framer Motion layout animations - The Blog of Maxime Heckel Building a Vaporwave scene with Three.js - The Blog of Maxime Heckel Cubic Bézier: from math to motion - The Blog of Maxime Heckel First steps with GPT-3 for frontend developers - The Blog of Maxime Heckel Building the perfect GitHub CI workflow for your frontend team - The Blog of Maxime Heckel Migrating to Next.js - The Blog of Maxime Heckel Static Tweets with MDX and Next.js - The Blog of Maxime Heckel Advanced animation patterns with Framer Motion - The Blog of Maxime Heckel Scrollspy demystified - The Blog of Maxime Heckel The Power of Composition with CSS Variables - The Blog of Maxime Heckel My first failed SwiftUI project - The Blog of Maxime Heckel Guide to creating animations that spark joy with Framer Motion - The Blog of Maxime Heckel Using Shortcuts and serverless to build a personal Apple Health API - The Blog of Maxime Heckel SEO mistakes I've made and how I fixed them - The Blog of Maxime Heckel Going native: SwiftUI from the perspective of a React developer - The Blog of Maxime Heckel Build your own preview deployment service - The Blog of Maxime Heckel The little guide to CI/CD for frontend developers - The Blog of Maxime Heckel Immigrating to the US - The Blog of Maxime Heckel The physics behind spring animations - The Blog of Maxime Heckel Generate screenshots of your code with a serverless function - The Blog of Maxime Heckel How to use Framer Motion with Emotion styled-components - The Blog of Maxime Heckel Data Fetching with NextJS: What I learned - The Blog of Maxime Heckel Learning in public - The Blog of Maxime Heckel Fixing the dark mode flash issue on server rendered websites - The Blog of Maxime Heckel How to fix NPM link duplicate dependencies issues - The Blog of Maxime Heckel Running scheduled cross-browser end-to-end tests on Github CI - The Blog of Maxime Heckel How I built my first custom ESLint rule - The Blog of Maxime Heckel React Lazy: a take on preloading views - The Blog of Maxime Heckel Automated UI accessibility testing with Cypress - The Blog of Maxime Heckel Building a GraphQL wrapper for the Docker API - The Blog of Maxime Heckel Switching off the lights - Adding dark mode to your React app - The Blog of Maxime Heckel Getting started with Typescript on Gatsby - The Blog of Maxime Heckel Rebuilding Redux with Hooks and Context - The Blog of Maxime Heckel Using Flow generics to type generic React components - The Blog of Maxime Heckel How to efficiently type your styled-components with Flow - The Blog of Maxime Heckel How I got started with Kubernetes on GKE - The Blog of Maxime Heckel React sub-components Part 3: Whitelisting sub-components with flow - The Blog of Maxime Heckel React sub-components Part 2: Using the new Context API - The Blog of Maxime Heckel React sub-components - The Blog of Maxime Heckel Running Golang tests with Jest - The Blog of Maxime Heckel No title No title
Asynchronous rendering with React - The Blog of Maxime Heckel
Maxime Heckel · 2018-11-07 · via Maxime Heckel's Blog

Since I’ve started playing with React a couple of years ago, I’ve always been a big fan of functional components. Their simplicity and conciseness make them easy to read and test. The problem though was that, until now, there was no way to do asynchronous calls which is the crucial part of most applications in the real world, so classes were always the way to go.
However, starting from React 16.6.0 and the new Suspense API, this is not an issue anymore, functional components can now perform asynchronous calls and render data that comes from them. In this post, I’m going to show you an up to date example so you can easily test the Suspense API.

Note: Although it’s available through the last official version of React, using Suspense as I’ll show you in this post is not yet intended for production. This example solely exists as an experiment.

What is Suspense in a nutshell?

Suspense basically suspends the rendering of a component while loading data from a cache. This means that our component will only show up once the whole tree is ready. If the data we’re trying to render is not in the cache, the cache throws a Promise. When the promise resolves, the rendering continues. 
While all of this is happening, Suspense will render a fallback component which could be for example a loading indicator, a message, or anything we usually render in our applications to signal the user that something asynchronous is happening.

A new way to build components

As of today, when we want to render a component that shows some data coming from an asynchronous call in React, we’re stuck with classes. We have to use the component lifecycle methods to ensure the call happens on mount, and use the local state to manage the loading state. We can see below a small example of a pattern that I’m sure pretty much every React developer had to follow:

React component doing an asynchronous call before rendering the data implemented using a Class

1

import React, { Component, Fragment } from 'react';

3

class ClassicAsync extends Component {

6

this.state = { loading: false, title: null };

10

fetch('https://jsonplaceholder.typicode.com/todos/')

11

.then((response) => response.json())

12

.then((json) => this.setState({ loading: false, data: json }));

15

renderList = (data) => {

19

<li style={{ listStyle: 'none' }} key={item.id}>

28

const { loading, data } = this.state;

32

<h2 style={{ textAlign: 'center' }}>

33

{`React: ${React.version} Demo`}

35

{loading ? 'Classic loading placeholder' : this.renderList(data)}

41

export default ClassicAsync;

How Suspense changes that? Well, quite a lot actually if you compare the code above with the following one:

React component doing an asynchronous call before rendering the data implemented using React Suspense.

1

import React, { Suspense, Fragment } from 'react';

4

const getDate = () => Fetcher.read();

7

const data = getData();

11

<li style={{ listStyle: 'none' }} key={item.id}>

21

<h2>{`React: ${React.version} Demo`}</h2>

22

<Suspense fallback={<div>Loading...</div>}>

As we can see with this example: no more class! Suspense is managing for us the loading state through the fallback prop, which is rendered until List is ready to be rendered, that is when the dependent asynchronous call resolves and returns the data. However, this is only a partial example. As stated in the first part, the rendering of List in this example is suspended while loading data from a cache, which is what the Fetcher function is all about.

Using react-cache

This is key for getting the example above to work. The caching part is needed for Suspense to read the data from the asynchronous call.
Before diving in the details, let’s look at how the Fetcher function is implemented for our example:

Fetcher resource implementation using functions from react-cache

1

import { unstable_createResource } from 'react-cache';

3

const Fetcher = unstable_createResource(() =>

4

fetcher('https://jsonplaceholder.typicode.com/todos').then((r) => r.json())

For this post I used react-cache. It’s a package made by the React core team that provides a basic cache that is going to store asynchronous data, like the data that we’re getting once our fetch call resolves, and allows us to access that data asynchronously. In the code snippet above we basically use the unstable_createResource function where we pass our asynchronous call, which will initiate a cache and store the resulting data into it. Accessing that data from the cache is done through the read function as we can see in the Code Snippet 2. However, this way of doing caching is currently not meant to be used in production (the React team emphasized this quite a bit in the README of this repository).

Full Example

Here’s the full example for this article:

The full example of a functional React component using the Suspense API

1

import React, { Suspense, Fragment } from 'react';

2

import { unstable_createResource } from 'react-cache';

4

const Fetcher = unstable_createResource(() =>

5

fetcher('https://jsonplaceholder.typicode.com/todos').then((r) => r.json())

8

const getDate = () => Fetcher.read();

11

const data = getData();

15

<li style={{ listStyle: 'none' }} key={item.id}>

25

<h2>{`React: ${React.version} Demo`}</h2>

26

<Suspense fallback={<div>Loading...</div>}>

I made this example available in a Github repository based on create-react-app so you can also give it a try and experiment with Suspense very quickly!

I really can’t wait for this pattern to be ready for production. Combining Suspense and the recently announced React hooks is getting us closer to building React apps fully based on functional components. If you want to learn more about Suspense here’s a really complete summary in a tweet from a member of the React team:

What to read next?
If you want to read more about React or frontend development, you can check the following articles: