In the ground since Mon Jan 27 2025
Last watered inMon Jan 27 2025
React use() Hook
React's use() hook is a powerful utility that unwraps Promises and Context values. It's essential for handling async data in client components, especially with Next.js 15+ where route parameters are now Promises.
What is use()?
The use() hook allows you to unwrap Promises and Context values synchronously in React components. It's React's solution for handling async data in client components where you can't use await.
Why It Exists
In React, you can't use await directly in component bodies (only in async functions). Client components can't be async functions, so use() provides a way to unwrap Promises synchronously while maintaining React's rendering model.
Basic Usage
Unwrapping Promises
Unwrapping Context
Before vs After (Next.js 15+ Migration)
Before (Next.js 14 and earlier)
After (Next.js 15+)
When to Use use() vs await
| Scenario | Use await | Use use() |
|----------|-------------|-------------|
| Server Components | ✅ Yes | ❌ No |
| Client Components | ❌ No | ✅ Yes |
| Async Functions | ✅ Yes | ❌ No |
| Component Body | ❌ No | ✅ Yes |
| Event Handlers | ✅ Yes | ❌ No |
Key Benefits
- Works in Client Components: No need to make the component async
- Suspense Integration: React can suspend while the Promise resolves
- Type-Safe: TypeScript understands the unwrapped type
- Consistent API: Same pattern for Promises and Context
How It Works Under the Hood
When you call use(promise):
- React checks if the Promise is resolved
- If resolved: Returns the value immediately
- If pending: Throws the Promise (Suspense catches it)
- React re-renders when the Promise resolves
This is why Suspense boundaries are important when using use() with Promises.
Error Handling
Always wrap use() in error boundaries when dealing with Promises that might reject:
Real-World Example: Next.js Route Params
This is the exact pattern used when handling async route parameters in Next.js 15+:
Related Concepts
- Suspense Boundaries: use() works seamlessly with Suspense for loading states
- Streaming: Enables progressive rendering as data becomes available
- Server Components: Server components use await, client components use use()
- React 19: The use() hook is part of React's modern async data handling
Production Considerations
- Error Handling: Always wrap use() in error boundaries
- Loading States: Use Suspense boundaries for pending Promises
- Type Safety: Ensure Promise types match expected values
- Performance: use() enables React to optimize rendering and streaming
Common Pitfalls
❌ Don't Use await in Client Components
✅ Use use() Instead
❌ Don't Forget Suspense Boundaries
✅ Wrap in Suspense
Why Next.js 15+ Made Params Async
Next.js 15+ made route parameters async to enable:
- Better Streaming: Progressive rendering as params resolve
- Suspense Integration: Proper loading states during navigation
- Performance: Optimized rendering and data fetching
- Consistency: Unified async data handling across the framework
The use() hook is React's elegant solution for handling this in client components!