Skip to content

enhance(react): useFetch() returns UsablePromise thenable for React.use()#3755

Merged
ntucker merged 2 commits intomasterfrom
usefetch-use-thenable
Mar 1, 2026
Merged

enhance(react): useFetch() returns UsablePromise thenable for React.use()#3755
ntucker merged 2 commits intomasterfrom
usefetch-use-thenable

Conversation

@ntucker
Copy link
Collaborator

@ntucker ntucker commented Mar 1, 2026

Motivation

Building on #3752, useFetch() now returns a proper thenable that works directly with React.use(). This makes use(useFetch(endpoint, args)) a drop-in equivalent to useSuspense(endpoint, args) — same suspend, resolve, error, and invalidation behavior — while also enabling parallel data fetching that avoids sequential waterfalls.

Solution

  • trackPromise.ts: Replace FetchPromise/RESOLVED/trackPromise() with UsablePromise/createFulfilled()/createRejected() — thenables with status/value/reason fields that React.use() reads synchronously.
  • useFetch.ts / useFetch.native.ts: Return fulfilled thenables with denormalized data when cached, rejected thenables on errors, and pending promises when fetching. Add GC tracking via countRef.
  • Tests (useFetch-use.web.tsx): Comprehensive test suite cloned from useSuspense.web.tsx and integration-endpoint.web.tsx, validating behavioral equivalence. Gated behind describeIf19 to skip on React 18.
  • Docs (useFetch.md): Updated with use() usage, parallel fetch pattern, behavior table for use(), and AsyncBoundary example.
  • Existing tests: Updated to validate thenable properties (status, value, then) and denormalized data on fulfilled thenables.

Made with Cursor

@cursor
Copy link

cursor bot commented Mar 1, 2026

You have run out of free Bugbot PR reviews for this billing cycle. This will reset on April 19.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@changeset-bot
Copy link

changeset-bot bot commented Mar 1, 2026

🦋 Changeset detected

Latest commit: 74d348d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@data-client/react Major
@data-client/img Major
@data-client/test Major
test-bundlesize Patch
coinbase-lite Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Mar 1, 2026

Size Change: 0 B

Total Size: 80.6 kB

ℹ️ View Unchanged
Filename Size
examples/test-bundlesize/dist/App.js 3.42 kB
examples/test-bundlesize/dist/polyfill.js 307 B
examples/test-bundlesize/dist/rdcClient.js 10.2 kB
examples/test-bundlesize/dist/rdcEndpoint.js 6.24 kB
examples/test-bundlesize/dist/react.js 59.7 kB
examples/test-bundlesize/dist/webpack-runtime.js 726 B

compressed-size-action

@codecov
Copy link

codecov bot commented Mar 1, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.05%. Comparing base (3c3bfe8) to head (74d348d).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3755   +/-   ##
=======================================
  Coverage   98.04%   98.05%           
=======================================
  Files         151      151           
  Lines        2818     2821    +3     
  Branches      552      553    +1     
=======================================
+ Hits         2763     2766    +3     
  Misses         11       11           
  Partials       44       44           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ntucker ntucker force-pushed the usefetch-use-thenable branch from e28ca69 to e000d86 Compare March 1, 2026 19:37
…se()

useFetch() now returns a thenable with status/value/reason that works
directly with React.use() — use(useFetch(endpoint, args)) behaves
identically to useSuspense(endpoint, args): suspends when loading,
returns denormalized data when cached, throws on errors, and
re-suspends on invalidation.

- Replace trackPromise/RESOLVED with createFulfilled/createRejected
- Add GC tracking via countRef
- Support parallel fetches (all useFetch() calls run before use() suspends)
- Add comprehensive test suite (React 19+ only via describeIf19)
- Update useFetch.md docs with use() patterns and parallel fetch examples

Made-with: Cursor
@ntucker ntucker force-pushed the usefetch-use-thenable branch from e000d86 to 99eea3c Compare March 1, 2026 19:41
@ntucker ntucker force-pushed the usefetch-use-thenable branch from ab21e82 to 74d348d Compare March 1, 2026 20:01
@ntucker ntucker merged commit 5783267 into master Mar 1, 2026
23 checks passed
@ntucker ntucker deleted the usefetch-use-thenable branch March 1, 2026 20:07
@github-actions github-actions bot mentioned this pull request Mar 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant