This is an example implementation of React Suspense using Error Boundaries (introduced in React 14) to emulate the behaviour of Suspense Boundaries. In essense, Suspense works by interupting rendering by throwing a Promise. Here, the Error Boundary is used to catch the promise, await the result, and rerender the sub-tree. This requires a very specific version of React where Error Boundaries are implemented, but Suspense Boundaries are not in any capacity. Here, we use 16.5.2.
The fetchCache
is the crux of the whole system. When it is called with a URL for the first time, a Promise is created and thrown which will resolve to the Response. Subsequent calls before the Promise resolves will re-throw the same Promise.
function Component() { // throws Promise<Data> const data = fetchCache.get("https://example.com/data.json") ... }
This Promise is caught at the SuspenseBoundary
. Remember, this is just a React Error Boundary. The SuspenseBoundary
suspends, the fallback Element is show, and the Promise is awaited. When it resolves, two things happen:
First, the fetchCache
updates its cache with the response data. This actually happens as the Promise resolves.
Second, the SuspenseBoundary
unsuspends, triggering a rerender of its sub-tree. This time, fetchCache.get("...")
resolves the data synchronously and Component
is able to fully render. At this point, any children of Component
that have their own Suspense functionality can begin their data fetching operations in the same manner.
function Component() { // returns Data const data = fetchCache.get("https://example.com/data.json") ... }
Because this relies on state, SSR is not supported. Furthermore, for nested components using Suspense, data is fetched in a waterfall fashion, leading to UIs that load piece-by-piece, slowly.
In the preview panel, click on an example post to see its lazily-loaded comments and other meta information. Try clicking out of and back into a post before it finishes loading. Try clicking out of and back into a post after it has loaded.