Skip to content

fix: use React.use if available#6229

Merged
schiller-manuel merged 1 commit intomainfrom
use-react-use
Dec 26, 2025
Merged

fix: use React.use if available#6229
schiller-manuel merged 1 commit intomainfrom
use-react-use

Conversation

@schiller-manuel
Copy link
Contributor

@schiller-manuel schiller-manuel commented Dec 26, 2025

Summary by CodeRabbit

  • Refactor
    • Improved React Suspense support for lazy routes and deferred components by leveraging React 18+ async capabilities
    • Enhanced component loading behavior to use modern React features when available, with automatic fallback for older environments
    • Simplified deferred component API for better integration with React's native async patterns

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 26, 2025

📝 Walkthrough

Walkthrough

The changes modernize asynchronous data handling in React Router by leveraging React's use hook for promise unwrapping. The useAwaited hook return type is simplified from a tuple to unwrapped data, and lazy route components conditionally apply React.use when available, enabling native Suspense support in React 19+.

Changes

Cohort / File(s) Summary
Hook return type modernization
packages/react-router/src/awaited.tsx
Return type changed from [T, DeferredPromise<T>] tuple to T (unwrapped data). Implements conditional logic: uses React.use(_promise) when available, bypassing deferral path. Removes DeferredPromise import.
Lazy component loading
packages/react-router/src/lazyRouteComponent.tsx
Updated fallback behavior to conditionally invoke React.use(load()) if React.use exists; otherwise throws promise. Enables Suspense support in newer React versions while maintaining compatibility.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • birkskyum

Poem

🐰 A rabbit hops through promises anew,
With React.use, the data shines through—
No tuples to unpack, just truth so pure,
Suspense flows freely, the path is sure! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: use React.use if available' accurately describes the main change in the pull request, which is to conditionally use React.use() instead of throwing promises.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch use-react-use

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f22b44a and cf249d2.

📒 Files selected for processing (2)
  • packages/react-router/src/awaited.tsx
  • packages/react-router/src/lazyRouteComponent.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript strict mode with extensive type safety for all code

Files:

  • packages/react-router/src/lazyRouteComponent.tsx
  • packages/react-router/src/awaited.tsx
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Implement ESLint rules for router best practices using the ESLint plugin router

Files:

  • packages/react-router/src/lazyRouteComponent.tsx
  • packages/react-router/src/awaited.tsx
🧬 Code graph analysis (1)
packages/react-router/src/lazyRouteComponent.tsx (1)
packages/nitro-v2-vite-plugin/src/index.ts (1)
  • load (188-195)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Preview
  • GitHub Check: Test
🔇 Additional comments (5)
packages/react-router/src/awaited.tsx (3)

16-26: LGTM: Fallback behavior is correct.

The fallback path for environments without React.use properly maintains the existing deferred promise behavior, handling all promise states correctly (pending → throw, error → throw error, success → return data).


52-52: Breaking change: useAwaited return type changed from [T, DeferredPromise<T>] to T.

This is intentional for React Router to support React 19's React.use() hook. The internal usage at line 52 is correctly updated. Verify that external consumers update their code if they relied on tuple destructuring; note that Vue and Solid router implementations retain the tuple return type.


10-15: React version compatibility verified — implementation is correct.

The React peerDependency requirement (>=18.0.0 || >=19.0.0) correctly supports both React 18 and React 19+. The conditional if (React.use) safely checks for React 19's native use hook while falling back to the defer() mechanism for React 18. The eslint-disable-next-line comment is appropriate because React.use may not be present in older @types/react versions. All usage of useAwaited is consistent with the updated return type T.

packages/react-router/src/lazyRouteComponent.tsx (2)

82-82: LGTM: ESLint disable is appropriate for runtime compatibility check.

The @typescript-eslint/no-unnecessary-condition disable is necessary here because this is a runtime check for backward compatibility with React versions prior to 19. TypeScript cannot determine at compile time which React version will be used at runtime.


83-87: Good modernization with React 19 Suspense support.

The conditional logic correctly enables native Suspense handling via React.use() when available, while maintaining backward compatibility with the legacy promise-throwing pattern.

The implementation is sound: when React.use(load()) is called, it suspends until the promise resolves, then the component re-renders with comp already set (via the .then() callback in load()), so the block won't be re-entered.


Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Dec 26, 2025

View your CI Pipeline Execution ↗ for commit cf249d2

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 12m 59s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 58s View ↗

☁️ Nx Cloud last updated this comment at 2025-12-26 01:11:04 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 26, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@6229

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@6229

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@6229

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@6229

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@6229

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@6229

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@6229

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@6229

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@6229

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@6229

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@6229

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@6229

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@6229

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@6229

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@6229

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@6229

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@6229

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@6229

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@6229

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@6229

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@6229

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@6229

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@6229

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@6229

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@6229

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@6229

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-fn-stubs@6229

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@6229

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@6229

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@6229

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@6229

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@6229

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@6229

@tanstack/vue-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router@6229

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-devtools@6229

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-ssr-query@6229

@tanstack/vue-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start@6229

@tanstack/vue-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-client@6229

@tanstack/vue-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-server@6229

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@6229

commit: cf249d2

@schiller-manuel schiller-manuel merged commit aa208f1 into main Dec 26, 2025
6 checks passed
@schiller-manuel schiller-manuel deleted the use-react-use branch December 26, 2025 01:16
naoya7076 pushed a commit to naoya7076/router that referenced this pull request Feb 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant