3 ms·
Great to see this--there are some nice features that encourage using standard web technologies like forms, and some solid quality of life improvements. However
by uhoh-itsmaciek 2y ago
Great to see this--there are some nice features that encourage using standard web technologies like forms, and some solid quality of life improvements.
However, I'm disappointed (but not surprised, this was listed as out of scope for 19) that triggering Suspense is still basically "use a framework that supports it." I have not been able to find any documentation or blog posts about the mechanism. I've tried to figure out how it works by looking at TanStack Query, but I've had limited success so far. I've found they're copying React's twist on Promises [1], but I haven't gotten this to work yet.
I know the general idea is you throw Promises, but Suspense explicitly forbids using promises created during rendering. This means you can't just interrupt the component's initial render to load some data, and then restart it when its data is available. This means the component needs to deal with null data somehow, instead of, e.g., being able to call a custom `useSomeData` hook and rely on it to first suspend and then return the loaded data. Not having to deal directly with loading states in individual components could simplify things quite a bit.
Has anyone explored this side of Suspense?
[1]: https://github.com/TanStack/query/blob/main/packages/query-core/src/thenable.ts https://github.com/TanStack/query/blob/main/packages/query-c...
- acemarke 2y agoYeah, _we library maintainers_ are feeling the same way :) - https://bsky.app/profile/acemarke.dev/post/3lcitbmmfss2i https://bsky.app/profile/acemarke.dev/post/3lcitbmmfss2i Big picture as I understand it: The legacy and always-undocumented-but-everyone-knew-about-it approach was throwing a promise while rendering. `use` still actually does the same thing, but it also attaches some extra status fields to that promise, _and_ checks to see if you're consistently passing in the _same_ promise reference. In other words, it's the job of an external data fetching library to keep track of what query entry is being asked for, create and save a promise per cache entry _outside_ of the React component tree, and then return that promise somehow so the app developer can pass it to the `use` hook. In a sense, it's an async `Map`. As another example of this, my former teammate Brian Vaughn (previously on the React core team) ended up building his own implementation of that behavior in the conveniently-named `suspense` package: - https://suspense.vercel.app/ https://suspense.vercel.app/ Ultimately, the `use` hook and Suspense _does_ do exactly what you're asking for - the rest of the component gets to assume the data _does_ exist, since `use` will only let the execution continue once the promise has resolved.
- uhoh-itsmaciek 2y agoOh awesome, thank you! I'll have to investigate this and play with it, but that makes sense.