use(): Lendo Promises e Context no React 19

Como a API use() do React 19 permite ler Promises e valores de Context direto na renderização, inclusive dentro de condicionais e loops, integrando-se nativamente com Suspense e error boundaries.

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

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.

documentação oficial

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.

Tecnologia:
react

Deixe seu Comentário!

Dúvida, sugestão ou só um "valeu!" — tudo é bem-vindo por aqui.

Comentário
Nome
Email
lock Seu e-mail não será publicado.