Ler o valor de uma Promise ou de um Context dentro de um componente sempre exigiu hooks como useContext (fixos no topo do componente, sem condicional) ou um emaranhado de useEffect e useState para esperar dados assíncronos. A API use(), introduzida no React 19, substitui boa parte disso: ela lê o valor resolvido de uma Promise ou de um Context diretamente durante a renderização, e pode ser chamada dentro de condicionais e loops — algo que nenhum hook tradicional permite.
Não é um hook comum
Hooks como useState e useContext precisam ser chamados sempre na mesma ordem, no topo do componente, nunca dentro de um if. O use() quebra essa regra de propósito: por isso o React o trata como uma API separada, e não como mais um hook na lista de Rules of Hooks.
function Avatar({ contexto, mostrarNome }) {
// isto quebraria com useContext, mas funciona com use()
if (mostrarNome) {
const tema = use(contexto);
return <span style={{ color: tema.cor }}>Usuário</span>;
}
return null;
}
Lendo uma Promise
Quando use() recebe uma Promise, o componente suspende até ela resolver — o React mostra o fallback do Suspense mais próximo enquanto espera, e troca pelo conteúdo real assim que o valor chega:
function PerfilUsuario({ promessaUsuario }) {
const usuario = use(promessaUsuario);
return <h2>{usuario.nome}</h2>;
}
function Pagina({ id }) {
const promessaUsuario = buscarUsuario(id); // retorna uma Promise
return (
<Suspense fallback={<p>Carregando...</p>}>
<PerfilUsuario promessaUsuario={promessaUsuario} />
</Suspense>
);
}
Se a Promise for rejeitada, o erro sobe para o error boundary mais próximo, exatamente como aconteceria com uma exceção lançada durante a renderização.
Lendo Context condicionalmente
Com Context, use() funciona como uma versão mais flexível de useContext(): lê o valor atual, mas pode ficar atrás de um retorno antecipado ou dentro de um loop:
const TemaContext = createContext('claro');
function Botao({ mostrarTema }) {
if (!mostrarTema) {
return <button>Confirmar</button>;
}
const tema = use(TemaContext);
return <button className={`btn-${tema}`}>Confirmar</button>;
}
Combinando com cache para evitar refetch
Chamar use() diretamente com uma nova Promise criada a cada renderização dispararia uma busca infinita. Por isso a Promise normalmente vem de fora do componente — de uma função de busca com cache, ou de uma Server Component que já resolveu os dados no servidor:
const cache = new Map();
function buscarUsuario(id) {
if (!cache.has(id)) {
cache.set(id, fetch(`/api/usuarios/${id}`).then(r => r.json()));
}
return cache.get(id);
}
Quando usar
- Ler dados assíncronos (Promises) diretamente no corpo de um componente, delegando o estado de carregamento para o
Suspensemais próximo. - Ler Context de forma condicional, sem precisar reestruturar o componente para manter o hook sempre no topo.
- Componentes que recebem uma Promise já iniciada por um componente pai ou por uma Server Component, evitando o padrão clássico de
useEffect+useState+ flag de loading.
Cuidados
Criar a Promise durante a própria renderização do componente que a consome (em vez de recebê-la via prop ou de uma função com cache) causa um novo fetch a cada renderização — o React não memoiza a Promise para você. Além disso, use() só suspende corretamente dentro de um componente React renderizado durante o ciclo de render; chamá-lo fora desse contexto (em um callback de evento, por exemplo) lança um erro.
Compatibilidade
A API use() foi introduzida e estabilizada no React 19 (dezembro de 2024), exportada diretamente do pacote react. Não exige nenhuma flag e funciona tanto em componentes renderizados no cliente quanto em React Server Components.
Conclusão
O use() não substitui useContext ou os hooks de estado no dia a dia, mas resolve dois casos que eles não conseguiam cobrir bem: ler Context fora do topo rígido de um componente e ler uma Promise direto na renderização, integrado nativamente com Suspense e error boundaries.
0 Comentário
Deixe seu Comentário!
Dúvida, sugestão ou só um "valeu!" — tudo é bem-vindo por aqui.