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.

import React, { use, Suspense } from 'react';

// 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 { use } from 'react';
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.

import { Component, Suspense, use } from 'react';

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 →