Data Fetching & Server State

Request, loading, success or error, render — and the parts that only show up in production: cancellation, deduplication, retries, pagination and background refresh.

The Life of a Fetch
▶ lab

Request, loading, success or error, render — and the fact that `fetch` resolves happily for a 500, has no deadline, and hands you a body you still have to parse.

Q · What actually happens between calling `fetch` and rendering data, and which of those steps can fail without ever throwing?
Loading, Error, Empty — The States You Did Not Render
▶ lab

An interaction has at least four states and usually five. The missing failure branch is the most common defect in frontend code, and empty is not loading.

Q · How many states does a piece of remote data actually have, and which of them is my interface silently missing?
Cancelling a Request Nobody Is Waiting For
▶ lab

`AbortController`, unmount, and the `AbortError` that must never be shown to a user — because abandonment is not failure.

Q · How do I stop a request whose answer nobody wants any more, and why must the error it produces never reach the user?
Five Components, One Request
▶ lab

In-flight coalescing and caching are two different mechanisms with two different windows. Confusing them is why "we have a cache" does not stop the thundering herd on mount.

Q · Five components mount and each asks for the same user — how many requests should leave the browser, and which mechanism prevents the other four?
Retries, and the Duplicate Order
▶ lab

Retrying a non-idempotent mutation is a correctness bug wearing resilience as a costume. Retry only what is safe, with backoff, jitter and a cap.

Q · Which failed requests may I retry automatically, and what turns a retry from resilience into a second charge on someone's card?
Pagination From the Interface Backwards
▶ lab

Offset gives you jump-to-page and gives you duplicates under insertion. Cursor gives you stability and takes away page numbers. Pick from the UI you owe, not from the API you were given.

Q · Offset or cursor — which one does the interface I am building actually require, and what does the other one make impossible?
Server State Is Not Your State
▶ lab

It has freshness, a cache, invalidation, refetching, synchronisation and an authority that lives somewhere else. Copy it into component state and it starts diverging immediately.

Q · Which of the values in my components are actually owned by a server, and what changes the moment I admit that?