React 19 introduces use() - a special hook that can read resources like promises and context.
Basic Syntax
jsximport { use } from 'react'; function UserProfile({ userPromise }) { const user = use(userPromise); return <h1>{user.name}</h1>; }
With Data Fetching
jsximport { use, Suspense } from 'react'; // Cache for promises const cache = new Map(); function fetchData(url) { if (!cache.has(url)) { cache.set(url, fetch(url).then(r => r.json())); } return cache.get(url); } function UserProfile({ userId }) { const user = use(fetchData(`/api/users/${userId}`)); return ( <div> <h1>{user.name}</h1> <p>{user.email}</p> </div> ); } function App() { return ( <Suspense fallback={<Spinner />}> <UserProfile userId="123" /> </Suspense> ); }
use() vs useEffect
| Feature | use() | useEffect |
|---|---|---|
| Suspense integration | ✅ | ❌ |
| Conditional calls | ✅ | ❌ |
| In loops | ✅ | ❌ |
| Loading state | Automatic | Manual |
| Error boundaries | Automatic | Manual |
Conditional use()
Unlike other hooks, use() can be called conditionally:
jsxfunction OptionalData({ shouldFetch }) { if (shouldFetch) { const data = use(fetchData('/api/data')); return <DataView data={data} />; } return <p>Click to load data</p>; }
use() with Context
use() can also read context values:
jsximport { use, createContext } from 'react'; const ThemeContext = createContext('light'); function Button() { // Can be called conditionally! const theme = use(ThemeContext); return <button className={theme}>Click me</button>; }
Error Handling with Error Boundaries
jsximport { ErrorBoundary } from 'react-error-boundary'; function App() { return ( <ErrorBoundary fallback={<ErrorMessage />}> <Suspense fallback={<Loading />}> <DataComponent /> </Suspense> </ErrorBoundary> ); }
If the promise rejects, the error boundary catches it automatically.