Busca en todas las páginas de la documentación
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
import { use, Suspense } from "react";
// Leyendo una promesa -- debe estar envuelta en Suspense
function UserProfile({ userPromise }: { userPromise: Promise<{ name: string; email: string }> }) {
const user = use(userPromise);
return (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
);
}
// Leyendo contexto -- reemplaza useContext
const ThemeContext = React.createContext<"light" | "dark">("light");
function ThemedButton() {
const theme = use(ThemeContext);
return <button className={theme === "dark" ? "bg-gray-800 text-white" : "bg-white"}>Haz clic en mí</button>;
}
// Uso
function App() {
const userPromise = fetchUser(1); // crea la promesa fuera del renderizado, o en un Server Component
return (
<ThemeContext value="dark">
<Suspense fallback={<p>Cargando usuario...</p>}>
<UserProfile userPromise={userPromise} />
</Suspense>
<ThemedButton />
</ThemeContext>
);
}Cuándo usarlo: Usa use() para leer una promesa pasada desde un Server Component o componente padre, o para leer condicionalmente contexto en ramas donde useContext no puede ser llamado.
// Un panel que carga condicionalmente diferentes datos según el rol del usuario
"use client";
import { use, Suspense, createContext } from "react";
type User = { id: string; name: string; role: "admin" | "viewer" };
type Stats = { revenue: number; users: number; orders: number };
type Activity = { id: string; description: string; timestamp: string };
const AuthContext = createContext<User | null>(null);
function DashboardContent({
statsPromise,
activityPromise,
}: {
statsPromise: Promise<Stats>;
activityPromise: Promise<Activity[]>;
}) {
const user = use(AuthContext);
if (!user) {
return <p>Por favor, inicia sesión.</p>;
}
// use() puede ser llamado condicionalmente -- esto es único entre los hooks de React
if (user.role === "admin") {
const stats = use(statsPromise);
return (
<div>
<h2>Panel de administración</h2>
<dl>
<dt>Ingresos</dt><dd>${stats.revenue.toLocaleString()}</dd>
<dt>Usuarios</dt><dd>{stats.users.toLocaleString()}</dd>
<dt>Pedidos</dt><dd>{stats.orders.toLocaleString()}</dd>
</dl>
</div>
);
}
const activity = use(activityPromise);
return (
<div>
<h2>Feed de actividad</h2>
<ul>
{activity.map((a) => (
<li key={a.id}>
{a.description} <time>{a.timestamp}</time>
</li>
))}
</ul>
</div>
);
}
export default function Dashboard({
user,
statsPromise,
activityPromise,
}: {
user: User | null;
statsPromise: Promise<Stats>;
activityPromise: Promise<Activity[]>;
}) {
return (
<AuthContext value={user}>
<Suspense fallback={<p>Cargando panel...</p>}>
<DashboardContent
statsPromise={statsPromise}
activityPromise={activityPromise}
/>
</Suspense>
</AuthContext>
);
}Lo que esto demuestra:
use(AuthContext) leyendo contexto sin useContextuse(promise) llamado condicionalmente dentro de un bloque if -- imposible con hooks tradicionalesuse() no es un hook en el sentido tradicional. No sigue las "reglas de hooks" -- puedes llamarlo dentro de bucles, condicionales y returns tempranos. Esto es lo que lo distingue de useContext.use() suspende el componente hasta que la promesa se resuelva. El límite <Suspense> más cercano muestra el fallback. Si la promesa se rechaza, el límite de error más cercano captura el error.use() se comporta idénticamente a useContext() -- lee el valor actual del proveedor más cercano arriba en el árbol.use() debe ser estable -- no crees una nueva promesa en cada renderizado. Las promesas deben venir desde Server Components, estar cacheadas o ser creadas fuera de la función de renderizado.use() se integra con las características concurrentes de React. Mientras una promesa está pendiente, React puede continuar renderizando otras partes del árbol.Server Component pasando una promesa a un Client Component:
// app/page.tsx (Server Component)
import UserCard from "./UserCard";
export default function Page() {
// Comienza a obtener pero NO esperes -- deja que el cliente lo resuelva
const userPromise = fetchUser(1);
return <UserCard userPromise={userPromise} />;
}// app/UserCard.tsx
"use client";
import { use } from "react";
export default function UserCard({ userPromise }: { userPromise: Promise<{ name: string }> }) {
const user = use(userPromise);
return <h2>{user.name}</h2>;
}Lectura condicional de contexto:
import { use, createContext } from "react";
const FeatureFlagContext = createContext<Set<string>>(new Set());
function FeatureGate({ flag, children }: { flag: string; children: React.ReactNode }) {
const flags = use(FeatureFlagContext);
if (!flags.has(flag)) return null;
return <>{children}</>;
}Encadenando promesas:
function OrderDetails({ orderPromise }: { orderPromise: Promise<{ id: string; userId: string }> }) {
const order = use(orderPromise);
// Puedes usar el valor resuelto para crear otra promesa
// pero cachéala para evitar recrearla en cada renderizado
const userPromise = useMemo(() => fetchUser(order.userId), [order.userId]);
const user = use(userPromise);
return (
<div>
<p>Pedido #{order.id}</p>
<p>Cliente: {user.name}</p>
</div>
);
}use<T>(promise: Promise<T>): T -- El tipo resuelto se infiere de la promesa.use<T>(context: React.Context<T>): T -- El tipo del valor del contexto se infiere.userPromise: Promise<User>.use() se importa desde "react": import { use } from "react".fetch() o new Promise() dentro del cuerpo del componente crea una nueva promesa en cada renderizado, causando bucles de suspense infinitos. Solución: Crea la promesa en un Server Component, componente padre o usa useMemo/cache para estabilizarla.<Suspense> cuando use() lee una promesa, React lanza un error. Solución: Envuelve el componente (o un ancestro) en <Suspense fallback={...}>.use() con promesas.Promise y Context son soportados. Los Observables, generadores e iterables asincronos no lo son. Solución: Convierte otras fuentes asincronos en promesas antes de pasarlas a use().use(MyContext), ten en cuenta que <MyContext.Provider> sigue funcionando pero la sintaxis preferida es <MyContext value={v}>. Solución: Migra a la sintaxis más corta.use() no cachea, deduplica o revalida. Lee una única promesa. Solución: Empareja con una capa de cacheo (React cache(), cacheo a nivel de framework, o una biblioteca como SWR/TanStack Query).| Enfoque | Cuándo elegir |
|---|---|
use(promise) | Leyendo una promesa desde un Server Component o fuente cacheada |
useContext(ctx) | Lectura tradicional de contexto (sigue funcionando, pero no puede ser llamado condicionalmente) |
use(context) | Lectura condicional de contexto en ramas |
| TanStack Query / SWR | Obtención completa de datos con cacheo, revalidación, paginación |
useEffect + useState | Patrón heredado de obtención al montar (sigue funcionando pero menos ergonómico) |
React.lazy | División de código de componentes (caso de uso diferente al de promesas de datos) |
use() puede ser llamado dentro de bucles, condicionales y returns tempranos -- no sigue las "reglas de hooks"useContext solo funciona con Contextuse() es el reemplazo preferido para useContext() en adelante<Suspense> cuando use() lee una promesa pendiente<Suspense fallback={...}>Sí. Este es el diferenciador clave con respecto a otros hooks:
function Dashboard({ user, statsPromise, activityPromise }) {
if (user.role === "admin") {
const stats = use(statsPromise);
return <AdminView stats={stats} />;
}
const activity = use(activityPromise);
return <ActivityFeed activity={activity} />;
}fetch() o new Promise() dentro del cuerpo del componente crea una nueva promesa en cada renderizadouseMemo/cache// Server Component -- NO esperes
export default function Page() {
const userPromise = fetchUser(1);
return <UserCard userPromise={userPromise} />;
}
// Client Component
"use client";
import { use } from "react";
export default function UserCard({ userPromise }) {
const user = use(userPromise);
return <h2>{user.name}</h2>;
}use() no cachea, deduplica ni revalida datoscache(), cacheo de framework, o una biblioteca) para necesidades de obtención de datos en producciónfunction OrderDetails({ orderPromise }) {
const order = use(orderPromise);
const userPromise = useMemo(
() => fetchUser(order.userId),
[order.userId]
);
const user = use(userPromise);
return <p>Pedido #{order.id} por {user.name}</p>;
}Usa useMemo para estabilizar la promesa dependiente y evitar la recreación en cada renderizado.
<MyContext.Provider value={v}> está deprecado<MyContext value={v}> directamente como el JSX del proveedoruse(MyContext) como useContext(MyContext) leen de cualquiera de las dos sintaxisPromise y React.Context son soportadosuse()// Promesa -- tipo resuelto inferido
const user: User = use<User>(userPromise);
// Contexto -- tipo de valor inferido
const theme: "light" | "dark" = use(ThemeContext);Importa desde "react": import { use } from "react".
type Props = {
dataPromise: Promise<{ id: string; name: string }>;
};
function MyComponent({ dataPromise }: Props) {
const data = use(dataPromise);
return <p>{data.name}</p>;
}Revisado por Chris St. John·Última actualización: 16 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥