Traditionally, React Hooks (like useState, useEffect, or useContext) followed strict Rules of Hooks: they could only be called at the top level of a function component and could never be placed inside if statements, loops, or nested functions.
With React 19, Meta introduced the new use API! Unlike standard hooks, use is a flexible API that can be invoked conditionally inside branches and loops. It handles two primary use-cases: unwrapping asynchronous Promises and reading Context dynamically.
1. Unwrapping Promises inside Components
When passed a Promise, use(promise) suspends the component until the Promise resolves. It integrates directly with React's <Suspense> boundary fallback system.
// 1. Child component receives Promise prop
function UserProfile({ userPromise }) {
// 'use' unwraps the resolved Promise directly during render!
const user = use(userPromise);
return (
<div className="card p-3 border-info shadow-sm">
<h4 class="text-primary">{user.name}</h4>
<p className="mb-1"><strong>Email:</strong> {user.email}</p>
<p className="mb-0 text-muted"><strong>Role:</strong> {user.role}</p>
</div>
);
}
// 2. Parent Container passing Promise to Suspense
export default function App() {
const userPromise = fetch('/api/user/101').then(res => res.json());
return (
<Suspense fallback={<div className="alert alert-info p-3"><i class="bi bi-arrow-repeat spin me-2"></i>Loading user profile...</div>}>
<UserProfile userPromise={userPromise} />
</Suspense>
);
}
2. Conditional Context Reading with `use(Context)`
Unlike useContext(ThemeContext) which must be called at the top level on every render cycle, use(ThemeContext) can be placed inside conditional blocks or loops!
import { ThemeContext } from './ThemeContext';
function NotificationBanner({ showCustomTheme, message }) {
// Valid in React 19! Conditional Context reading
if (showCustomTheme) {
const theme = use(ThemeContext);
return (
<div style={{ backgroundColor: theme.bg, color: theme.color, padding: '15px', borderRadius: '5px' }}>
{message}
</div>
);
}
return <div className="alert alert-secondary">{message}</div>;
}
3. Error Handling with Error Boundaries
If the Promise passed to use(promise) rejects, the component throws an error that can be caught gracefully by an Error Boundary component.
class ErrorBoundary extends Component {
state = { hasError: false, error: null };
static getDerivedStateFromError(error) { return { hasError: true, error }; }
render() {
if (this.state.hasError) {
return <div className="alert alert-danger">Failed to load data: {this.state.error.message}</div>;
}
return this.props.children;
}
}
4. Rules & Comparison Matrix
| Feature | Traditional Hooks (e.g., useContext) |
React 19 use API |
|---|---|---|
| Top-Level Execution | Mandatory. Must be called at top of component. | Flexible. Can be called conditionally inside if or loops. |
| Promise Resolution | Requires useEffect + useState boilerplate. |
Direct resolution during render via use(promise) + Suspense. |
| Context Reading | Top-level only via useContext(). |
Conditional reading allowed via use(Context). |
Master React 19 Data Streaming with Telugu IT Tutorials
Learn Server Components, Suspense, and full-stack React 19 architecture in our interactive live courses. View React Courses →