use
es una API de React que te permite leer el valor de un recurso como una Promesa o contexto.
const value = use(resource);
Referencia
use(resource)
Llama a use
en tu componente para leer el valor de un recurso como una Promesa o contexto.
import { use } from 'react';
function MessageComponent({ messagePromise }) {
const message = use(messagePromise);
const theme = use(ThemeContext);
// ...
A diferencia de los Hooks de React, use
puede ser llamado dentro de bucles y condicionales como if
. Al igual que otros Hooks de React, la función que llama a use
tiene que ser un componente o Hook.
Cuando es llamado con una Promesa, la API use
se integra con Suspense
y barreras de error. El componente que llama a use
se suspende mientras que la Promesa pasada a use
es pendiente. Si el componente que llama a use
es envuelto en una barrera de Suspense, el fallback será mostrado. Una vez que la Promesa es resuelta, el fallback de Suspense es remplazada por los componentes renderizados usando los datos devueltos por la API use
. Si la Promesa pasada a use
es rechazada, se mostrará el fallback del error mas cercano a la barrera de error.
Parámetros
resource
: esta es la fuente de los datos de los que quieres leer un valor. Un recurso puede ser una Promesa o un contexto.
Devuelve
La API use
devuelve el valor que se leyó del recurso como el valor resuelto de una Promesa o contexto.
Advertencias
- La API
use
debe ser llamado dentro de un componente o un Hook. - Cuando se recupera datos en un Componente del Servidor, se prefiere el uso de
async
yawait
por encima deuse
.async
yawait
retoman el renderizado desde el punto donde se invocóawait
, mientras queuse
vuelve a renderizar el componente después de que se resuelvan los datos. - Se prefiere la creación de Promesas en los Componente del Servidor y pasarlos a los Componente del Clientes por encima de crear Promesas en los Componente del Clientes. Las Promesas creadas en los Componente del Clientes son recreadas en cada renderizado. Las Promesas que son pasadas de un Componente del Servidor a un Componente del Cliente son estables en todos los renderizados. Ver este ejemplo.
Uso
Leer contexto con use
Cuando un contexto se pasa a use
, funciona de manera similar a useContext
. Mientras useContext
debe ser llamado en el nivel mas alto de tu componente, use
puede ser llamado dentro de condicionales como if
y en bucles como for
. Se prefiere use
por encima de useContext
porque es más flexible.
import { use } from 'react';
function Button() {
const theme = use(ThemeContext);
// ...
use
devuelve el valor de contexto para el contexto que pasas. Para determinar el valor del contexto, React busca en el árbol de componentes y encuentra el proveedor de contexto más cercano arriba para ese contexto en particular.
Para pasar el contexto a un Button
, envuélvalo en uno de sus componentes padres en el proveedor de contexto correspondiente.
function MyPage() {
return (
<ThemeContext.Provider value="dark">
<Form />
</ThemeContext.Provider>
);
}
function Form() {
// ... renderiza botones adentro ...
}
No importa cuántas capas de componentes hay entre el proveedor y el Button
. Cuando un Button
en cualquier lugar dentro de un Form
llama a use(ThemeContext)
, recibirá "dark"
como valor.
A diferencia de useContext
, use
se puede llamar en condicionales y bucles como if
.
function HorizontalRule({ show }) {
if (show) {
const theme = use(ThemeContext);
return <hr className={theme} />;
}
return false;
}
use
se llama desde dentro de una declaración if
, lo que te permite leer valores condicionalmente de un contexto.
import { createContext, use } from 'react'; const ThemeContext = createContext(null); export default function MyApp() { return ( <ThemeContext.Provider value="dark"> <Form /> </ThemeContext.Provider> ) } function Form() { return ( <Panel title="Bienvenido"> <Button show={true}>Registrarse</Button> <Button show={false}>Iniciar sesión</Button> </Panel> ); } function Panel({ title, children }) { const theme = use(ThemeContext); const className = 'panel-' + theme; return ( <section className={className}> <h1>{title}</h1> {children} </section> ) } function Button({ show, children }) { if (show) { const theme = use(ThemeContext); const className = 'button-' + theme; return ( <button className={className}> {children} </button> ); } return false }
Transmisión de datos del servidor al cliente (streaming)
Se puede transmitir un flujo de datos del servidor al cliente (streaming) pasando una Promesa como una prop desde un Componente del Servidor a un Componente del Cliente.
import { fetchMessage } from './lib.js';
import { Message } from './message.js';
export default function App() {
const messagePromise = fetchMessage();
return (
<Suspense fallback={<p>Esperando mensaje...</p>}>
<Message messagePromise={messagePromise} />
</Suspense>
);
}
El Componente del Cliente toma la Promesa que ha recibido como una prop y la pasa a la API use
. Esto permite al Componente del Cliente leer el valor de la Promesa que fue inicialmente creada por el Componente del Servidor.
// message.js
'use client';
import { use } from 'react';
export function Message({ messagePromise }) {
const messageContent = use(messagePromise);
return <p>Aquí está el mensaje: {messageContent}</p>;
}
Debido a que Message
está envuelto en Suspense
, el fallback se mostrará hasta que la Promesa esté resuelta. Cuando se resuelva la Promesa, el valor será leído por la API use
y el componente Message
reemplazará el fallback de Suspense.
"use client"; import { use, Suspense } from "react"; function Message({ messagePromise }) { const messageContent = use(messagePromise); return <p>Aquí está el mensaje: {messageContent}</p>; } export function MessageContainer({ messagePromise }) { return ( <Suspense fallback={<p>⌛Descargando mensaje...</p>}> <Message messagePromise={messagePromise} /> </Suspense> ); }
Profundizar
Una Promesa se puede pasar de un Componente del Servidor a un Componente del Cliente y resolverse en el Componente del Cliente con la API use
. También puedes resolver la Promesa en un Componente del Servidor con await
y pasar los datos requeridos al Componente del Cliente como una prop.
export default async function App() {
const messageContent = await fetchMessage();
return <Message messageContent={messageContent} />
}
Pero el uso de await
en un Componente del Servidor bloqueará su renderizado hasta que finalice la declaración de await
. Pasar una Promesa de un Componente del Servidor a un Componente del Cliente evita que la Promesa bloquee la representación del Componente del Servidor.
Lidiar con las promesas rechazadas
En algunas ocasiones una Promesa pasada a use
puede ser rechazada. Puedes manejar Promesas rechazadas de estas maneras:
- Mostrar un error a los usuarios con una barrera de error.
- Proporcionar un valor alternativo con
Promise.catch
Mostrar un error a los usuarios con una barrera de error
Si quieres mostrar un error a tus usuarios cuando se rechaza una Promesa, puedes usar una barrera de error. Para usar una barrera de error, envuelve el componente donde estás llamando a la API use
en una barrera de error. Si se rechaza la Promesa que fue pasada a use
, se mostrará el fallback para la barrera de error.
"use client"; import { use, Suspense } from "react"; import { ErrorBoundary } from "react-error-boundary"; export function MessageContainer({ messagePromise }) { return ( <ErrorBoundary fallback={<p>⚠️Algo ha salido mal</p>}> <Suspense fallback={<p>⌛Descargando el mensaje...</p>}> <Message messagePromise={messagePromise} /> </Suspense> </ErrorBoundary> ); } function Message({ messagePromise }) { const content = use(messagePromise); return <p>Aquí está el mensaje: {content}</p>; }
Proporcionar un valor alternativo con Promise.catch
Si quieres proporcionar un valor alternativo cuando se rechaza la Promesa pasada a use
, puedes usar el método catch
de la Promesa.
import { Message } from './message.js';
export default function App() {
const messagePromise = new Promise((resolve, reject) => {
reject();
}).catch(() => {
return "no se encontró ningún mensaje nuevo.";
});
return (
<Suspense fallback={<p>Esperando mensaje...</p>}>
<Message messagePromise={messagePromise} />
</Suspense>
);
}
Para usar el método catch
de la Promesa, llama a catch
en el objeto de la Promesa. catch
toma un solo argumento: una función que toma un mensaje de error como un argumento. Lo que sea devuelto por la función pasada a catch
se utilizará como valor resuelto de la Promesa.
Solución de problemas
“Excepción de Suspense: ¡Esto no es un error real!”
Estás llamando a use
fuera de un Componente de React o función Hook, o llamando a use
en un bloque try-catch. Si estás llamando a use
dentro de un bloque try-catch, envuelve tu componente en una barrera de error o llama al catch
de la Promesa para detectar el error y resolver la Promesa con otro valor. Ver estos ejemplos.
Si estás llamando a use
fuera de un Componente de React o función Hook, mueve la llamada de use
a un Componente de React o función Hook.
function MessageComponent({messagePromise}) {
function download() {
// ❌ la función que llama a `use` no es un componente ni un Hook
const message = use(messagePromise);
// ...
En su lugar, llama a use
fuera de las clausuras de cualquier componente, donde la función que llama a use
es un Componente o un Hook.
function MessageComponent({messagePromise}) {
// ✅ `use` está siendo llamado desde un componente.
const message = use(messagePromise);
// ...