RFC: accept promises as props to native DOM elements #225
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Full text here
Summary
React should accept promises as props and text nodes for native DOM-elements.
While a passed promise has not resolved yet, react should suspend the tree from the DOM-element upwards.
When one such promise resolves, react should trigger a re-render just like it
does with the regular suspense API.
Basic example
Motivation
This API would significantly improve the developer experience when building
optimistic UIs. React's real strength compared to other frameworks such as Preact,
Svelte and server-side MVC frameworks such as Phoenix, Laravel and Spring Boot
is that it can handle client side state at scale and therefore support
large application-like interfaces. For application-like interfaces, optimistic UI is
imperative to provide a great user experience.
Passing promises directly to native DOM elements would make it possible to shift
suspending from the component where a fetch call is made towards the actual DOM elements
where the fetched values are needed:
This would make it possible to optimistically render a parent component that fetches data
and add suspense boundaries much further down the DOM tree just with react's built-in APIs.
Another motivation for this is to prevent data-fetching waterfalls. With this API, it would
be much easier to render all data-fetching components at once while suspending only the
parts of the tree that actually use the fetched data:
This would, of course, also work very nicely with server components, where much more of the DOM could
be streamed to the client before an actual data-fetching call resolves.
Detailed design
It is really pretty simple from a high-level point of view:
If a native element receives a promise as a prop or child, it suspends.
Once the promise resolves, it renders the resolved value.
Drawbacks
From my point of view the largest drawbacks are
real HTML as possible.
a native element is a promise.
Alternatives
Apollo and other data-fetching libraries already enable optimistic rendering.
Something similar (but far not as elegant) can be implemented as a library and I'm working on that.
Adoption strategy
This is not a breaking change. Libraries could slowly adopt this strategy instead
of their custom optimisic rendering solutions.
How we teach this
I suppose this should become the recommended way to use suspense for data fetching and
would expect this to get its own section in the docs.
As gradual adoption is not a problem at all developers would learn about it through the
regular release notes and release channels. Consumers of data fetching libraries and frameworks
would probably learn about it through their library or framework's release notes.
I would e.G. love to have an option to have Next.js render a page immediately as soon as the
js-bundle is loaded and pass server side props as a promise to a page and would expect such features
to show up in Next.js' release notes.
Unresolved questions
¯_(ツ)_/¯