Skip to content

Suspense and Concurrent Mode in ReSift #32

@ricokahler

Description

@ricokahler

The React team has finally released docs for suspense for data fetching and concurrent mode 🎉. They've clarified a bit of how it works and how its intended to be used, and my first impression is that it can actually fit within our current APIs nicely without any big breaking changes.

Reading their docs is a prereq to this issue. and so is watching this talk from the Relay team.

They say the correct way to use suspense is to "render as you fetch", meaning that you reveal parts of the API that make sense to reveal if you have enough data to reveal it. Here is a direct quote from their new docs:

Although it’s technically doable, Suspense is not currently intended as a way to start fetching data when a component renders. Rather, it lets components express that they’re “waiting” for data that is already being fetched.

which sums up the idea of "render as you fetch".


What does this mean for ReSift?

Well, fortunately, not that much. Many simple fetching libraries rely on "fetch-on-render" techniques because the state of the fetches inflight live in the component. Fortunately for ReSift, the state of our fetches lives in global state, and we've already discovered that we need to split up fetching (e.g. dispatch(getPerson())) from getting the data (e.g. useData(getPerson)).

This means that we can advise users to initiate fetches for components at some higher component level to abide by the "already being fetched"/"fetch-as-you-render" philosophy. This is possible because our useDispatch and useData APIs are separate.

Initial thoughts on Suspense and Concurrent Mode in ReSift (revised)

Here's how I think it should work (disclaimer: i have not tested to see if this will work):

  1. useData should suspend by default (i.e. throw a promise) and we should add a configuration object with the flag noSuspend (or maybe allowNull or similar) to allow the hook to return null instead of causing suspense (e.g. useData(getPerson, { noSuspend: true })).
  2. we advise our users to dispatch higher up in the tree to prevent "fetch on render" patterns*
  3. we make dispatch work with startTransition of useTransition

I still have to test whether this approach makes sense but there's my initial thoughts on how that should work.

Adoption strategy/road map concerns

Suspense + concurrent mode should stay in an experimental as long as React has them in an experimental channel. See #37 for more details.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions