use
es un Hook 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 otros 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, el Hook de 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 el Hook 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
El Hook use
devuelve el valor que se leyó del recurso como el valor resuelto de una Promesa o contexto.
Advertencias
- El Hook
use
debe ser llamado dentro de un componente o un Hook. - Cuando se recupera datos en un Server Component, se prefiere el uso de
async
yawait
por encima deuse
.async
yawait
retoman la renderización 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 Server Components y pasarlos a los Client Components por encima de crear Promesas en los Client Components. Las Promesas creadas en los Client Components son recreadas en cada renderización. Las Promesas que son pasadas de un Server Component a un Client Component son estables en todas las renderizaciones. 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 }
Transmitir datos del servidor al cliente
Los datos pueden ser transmitidos del servidor al cliente pasándole una Promesa como un prop desde un Server Component a un Client Component.
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 Client Component toma la Promesa que ha recibido como un prop y lo pasa al Hook use
. Esto permite al Client Component leer el valor de la Promesa que fue inicialmente creada por el Server Component.
// 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 va a ser leido por el Hook 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 Server Component a un Client Component y resolverse en el Client Component con el Hook use
. También puedes resolver la Promesa en un Server Component con await
y pasar los datos requeridos al Client Component como un prop.
export default function App() {
const messageContent = await fetchMessage();
return <Message messageContent={messageContent} />
}
Pero el uso de await
en un Server Component bloqueará su renderizado hasta que finalice la declaración de await
. Pasar una Promesa de un Server Component a un Client Component evita que la Promesa bloquee la representación del Server Component.
Lidiar con las promesas rechazadas
En algunas ocaciones 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 al Hook 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 los cierres de cualquier componente, donde la función que llama a use
es un componente o gancho.
function MessageComponent({messagePromise}) {
// ✅ `use` está siendo llamado desde un componente.
const message = use(messagePromise);
// ...