use

use() is a Hook, introduced in React 19, for reading the value of a resource during render — either a Promise or a Context. Called with a Context (created via createContext()), it behaves like useContext(): it returns the value from the closest matching provider above it in the tree. Called with a Promise, it suspends the component until that Promise settles, integrating directly with Suspense and error boundaries. Import it from 'react'.

Unlike every other Hook, use() is not bound by the Rules of Hooks: it can be called conditionally, inside if blocks, loops, or after an early return. Every other Hook — useState, useContext, useEffect, and the rest — must always be called unconditionally, in the same order, on every render. use() is the one exception.

Two rules still apply, though. A Promise passed to use() must be cached so the same instance is reused across re-renders — creating a brand-new Promise on every render (say, calling fetch() directly in the component body) makes the component suspend repeatedly instead of settling once. And since use() cannot be wrapped in a try/catch block, a rejected Promise must instead be caught by wrapping the component in an error boundary. React 19 ships no UMD/CDN global build, so — like the other React-19-exclusive examples on this site — the demos below load React via ES modules through an import map instead of the usual React 18 UMD script tags.

Click the button to re-render the App component. Because fetchMessage() always returns the same cached Promise instance, use() only suspends the very first time — once the Promise has resolved, later re-renders read it instantly instead of showing the Suspense fallback again.
RESETRUNFULL
<!DOCTYPE html><html><head>
<script type="importmap">
{"imports": {"react": "https://esm.sh/react@19", "react-dom/client": "https://esm.sh/react-dom@19/client"}}
</script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head><body>
<div id="root"></div>
<script type="text/babel" data-type="module" data-presets="react">
import { Suspense, use, useState } from 'react';
import { createRoot } from 'react-dom/client';

let cachedPromise;
function fetchMessage() {
  if (!cachedPromise) {
    cachedPromise = new Promise((resolve) => {
      setTimeout(() => resolve('Hello from the server!'), 1000);
    });
  }
  return cachedPromise;
}

function Message({ messagePromise }) {
  const text = use(messagePromise);
  return <p>{text}</p>;
}

function App() {
  const [count, setCount] = useState(0);
  const messagePromise = fetchMessage();
  return (
    <div>
      <button onClick={() => setCount(c => c + 1)}>Re-render (clicked {count} times)</button>
      <Suspense fallback={<p>Loading message...</p>}>
        <Message messagePromise={messagePromise} />
      </Suspense>
    </div>
  );
}
createRoot(document.getElementById('root')).render(<App />);
</script>
</body></html>
Click Toggle. ThemedLabel returns early (before ever calling use()) when show is false — something no other Hook is allowed to do, since use() is exempt from the Rules of Hooks.
RESETRUNFULL
<!DOCTYPE html><html><head>
<script type="importmap">
{"imports": {"react": "https://esm.sh/react@19", "react-dom/client": "https://esm.sh/react-dom@19/client"}}
</script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head><body>
<div id="root"></div>
<script type="text/babel" data-type="module" data-presets="react">
import { createContext, use, useState } from 'react';
import { createRoot } from 'react-dom/client';

const ThemeContext = createContext('light');

function ThemedLabel({ show }) {
  if (!show) {
    return <p>(hidden)</p>;
  }
  const theme = use(ThemeContext); // OK here, even after the early return above!
  return <p>Current theme: {theme}</p>;
}

function App() {
  const [show, setShow] = useState(true);
  return (
    <ThemeContext.Provider value="dark">
      <button onClick={() => setShow(s => !s)}>Toggle</button>
      <ThemedLabel show={show} />
    </ThemeContext.Provider>
  );
}
createRoot(document.getElementById('root')).render(<App />);
</script>
</body></html>