use é uma API do React que permite que você leia o valor de um recurso como uma Promise ou um contexto.
const value = use(resource);Referência
use(resource)
Chame use em seu componente para ler o valor de um recurso como uma Promise ou contexto.
import { use } from 'react';
function MessageComponent({ messagePromise }) {
const message = use(messagePromise);
const theme = use(ThemeContext);
// ...Ao contrário dos React Hooks, use pode ser chamado dentro de loops e instruções condicionais como if. Como os React Hooks, a função que chama use deve ser um Componente ou Hook.
Quando chamado com uma Promise, a API use se integra com Suspense e error boundaries. O componente que chama use suspende enquanto a Promise passada para use está pendente. Se o componente que chama use for encapsulado em um limite Suspense, o fallback será exibido. Uma vez que a Promise for resolvida, o fallback Suspense é substituído pelos componentes renderizados usando os dados retornados pela API use. Se a Promise passada para use for rejeitada, o fallback do Error Boundary mais próximo será exibido.
Parâmetros
resource: esta é a fonte dos dados de onde você deseja ler um valor. Um recurso pode ser uma Promise ou um contexto.
Retornos
A API use retorna o valor que foi lido do recurso, como o valor resolvido de uma Promise ou contexto.
Ressalvas
- A API
usedeve ser chamada dentro de um Componente ou um Hook. - Ao buscar dados em um Server Component, prefira
asynceawaitem vez deuse.asynceawaitretomam a renderização do ponto em queawaitfoi invocado, enquantouserenderiza novamente o componente após os dados serem resolvidos. - Prefira criar Promises em Server Components e passá-las para Client Components em vez de criar Promises em Client Components. Promises criadas em Client Components são recriadas a cada renderização. Promises passadas de um Server Component para um Client Component são estáveis em todas as re-renderizações. Veja este exemplo.
Uso
Lendo o contexto com use
Quando um contexto é passado para use, ele funciona de forma semelhante a useContext. Enquanto useContext deve ser chamado no nível superior do seu componente, use pode ser chamado dentro de condicionais como if e loops como for. use é preferível a useContext porque é mais flexível.
import { use } from 'react';
function Button() {
const theme = use(ThemeContext);
// ...use retorna o valor do contexto para o contexto que você passou. Para determinar o valor do contexto, o React pesquisa na árvore de componentes e encontra o provider de contexto mais próximo acima para aquele contexto específico.
Para passar o contexto para um Button, envolva-o ou um de seus componentes pai no provider de contexto correspondente.
function MyPage() {
return (
<ThemeContext value="dark">
<Form />
</ThemeContext>
);
}
function Form() {
// ... renders buttons inside ...
}Não importa quantas camadas de componentes existam entre o provider e o Button. Quando um Button em qualquer lugar dentro de Form chama use(ThemeContext), ele receberá "dark" como o valor.
Ao contrário de useContext, use pode ser chamado em condicionais e loops como if.
function HorizontalRule({ show }) {
if (show) {
const theme = use(ThemeContext);
return <hr className={theme} />;
}
return false;
}use é chamado de dentro de uma instrução if, permitindo que você leia condicionalmente valores de um Contexto.
import { createContext, use } from 'react'; const ThemeContext = createContext(null); export default function MyApp() { return ( <ThemeContext value="dark"> <Form /> </ThemeContext> ) } function Form() { return ( <Panel title="Welcome"> <Button show={true}>Sign up</Button> <Button show={false}>Log in</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 }
Streaming de dados do servidor para o cliente
Os dados podem ser transmitidos do servidor para o cliente passando uma Promise como uma prop de um Server Component para um Client Component.
import { fetchMessage } from './lib.js';
import { Message } from './message.js';
export default function App() {
const messagePromise = fetchMessage();
return (
<Suspense fallback={<p>waiting for message...</p>}>
<Message messagePromise={messagePromise} />
</Suspense>
);
}O Client Component então pega a Promise que recebeu como prop e a passa para a API use. Isso permite que o Client Component leia o valor da Promise que foi inicialmente criada pelo Server Component.
// message.js
'use client';
import { use } from 'react';
export function Message({ messagePromise }) {
const messageContent = use(messagePromise);
return <p>Here is the message: {messageContent}</p>;
}Como o Message é encapsulado em Suspense, o fallback será exibido até que a Promise seja resolvida. Quando a Promise for resolvida, o valor será lido pela API use e o componente Message substituirá o fallback Suspense.
"use client"; import { use, Suspense } from "react"; function Message({ messagePromise }) { const messageContent = use(messagePromise); return <p>Here is the message: {messageContent}</p>; } export function MessageContainer({ messagePromise }) { return ( <Suspense fallback={<p>⌛Downloading message...</p>}> <Message messagePromise={messagePromise} /> </Suspense> ); }
Deep Dive
Uma Promise pode ser passada de um Server Component para um Client Component e resolvida no Client Component com a API use. Você também pode resolver a Promise em um Server Component com await e passar os dados necessários para o Client Component como uma prop.
export default async function App() {
const messageContent = await fetchMessage();
return <Message messageContent={messageContent} />
}Mas usar await em um Server Component bloqueará sua renderização até que a instrução await seja finalizada. Passar uma Promise de um Server Component para um Client Component impede que a Promise bloqueie a renderização do Server Component.
Lidando com Promises rejeitadas
Em alguns casos, uma Promise passada para use pode ser rejeitada. Você pode lidar com Promises rejeitadas de duas formas:
- Exibir um erro para os usuários com um error boundary.
- Fornecer um valor alternativo com
Promise.catch
Exibindo um erro para os usuários com um error boundary
Se você deseja exibir um erro para seus usuários quando uma Promise é rejeitada, pode usar um error boundary. Para usar um error boundary, envolva o componente onde você está chamando a API use em um error boundary. Se a Promise passada para use for rejeitada, o fallback para o error boundary será exibido.
"use client"; import { use, Suspense } from "react"; import { ErrorBoundary } from "react-error-boundary"; export function MessageContainer({ messagePromise }) { return ( <ErrorBoundary fallback={<p>⚠️Something went wrong</p>}> <Suspense fallback={<p>⌛Downloading message...</p>}> <Message messagePromise={messagePromise} /> </Suspense> </ErrorBoundary> ); } function Message({ messagePromise }) { const content = use(messagePromise); return <p>Here is the message: {content}</p>; }
Fornecendo um valor alternativo com Promise.catch
Se você deseja fornecer um valor alternativo quando a Promise passada para use é rejeitada, você pode usar o método catch da Promise.
import { Message } from './message.js';
export default function App() {
const messagePromise = new Promise((resolve, reject) => {
reject();
}).catch(() => {
return "no new message found.";
});
return (
<Suspense fallback={<p>waiting for message...</p>}>
<Message messagePromise={messagePromise} />
</Suspense>
);
}Para usar o método catch da Promise, chame catch no objeto Promise. catch recebe um único argumento: uma função que recebe uma mensagem de erro como um argumento. Qualquer coisa que for retornada pela função passada para catch será usada como o valor resolvido da Promise.
Solução de problemas
“Suspense Exception: This is not a real error!”
Você está chamando use fora de um Componente ou função Hook do React, ou chamando use em um bloco try-catch. Se você estiver chamando use dentro de um bloco try-catch, envolva seu componente em um error boundary, ou chame o catch da Promise para capturar o erro e resolver a Promise com outro valor. Veja estes exemplos.
Se você estiver chamando use fora de um Componente ou função Hook do React, mova a chamada use para um Componente ou função Hook do React.
function MessageComponent({messagePromise}) {
function download() {
// ❌ a função que chama `use` não é um Componente ou Hook
const message = use(messagePromise);
// ...Em vez disso, chame use fora de quaisquer fechamentos de componente, onde a função que chama use é um Componente ou Hook.
function MessageComponent({messagePromise}) {
// ✅ `use` está sendo chamado de um componente.
const message = use(messagePromise);
// ...