Hook useDeferredValue
Adie o carregamento de uma parte da UI para manter o restante responsivo durante renderizações caras.
Busque em todas as páginas da documentação
Adie o carregamento de uma parte da UI para manter o restante responsivo durante renderizações caras.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Cartão de receita de referência rápida - pronto para copiar e colar.
const deferredQuery = useDeferredValue(query);
// O componente que usa deferredQuery re-renderiza com menor prioridade
<SearchResults query={deferredQuery} />
// Detectar conteúdo desatualizado
const isStale = deferredQuery !== query;Quando usar isso: Você tem um valor que muda rapidamente (como a entrada de pesquisa) impulsionando uma renderização cara do filho, e você quer que a entrada permaneça responsiva enquanto o filho se atualiza.
"use client";
import { memo, useDeferredValue, useState } from "react";
const HeavyList = memo(function HeavyList({ query }: { query: string }) {
const items = Array.from({ length: 5000 }, (_, i) => `Resultado ${i}: ${query}`);
return (
<ul className="max-h-64 overflow-y-auto text-sm">
{items
.filter((item) => item.toLowerCase().includes(query.toLowerCase()))
.slice(0, 100)
.map((item, i) => (
<li key={i} className="py-0.5">{item}</li>
))}
</ul>
);
});
export function DeferredSearch() {
const [query, setQuery] = useState("");
const deferredQuery = useDeferredValue(query);
const isStale = deferredQuery !== query;
return (
<div className="space-y-3">
<input
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Digite para pesquisar..."
className="border rounded px-3 py-2 w-full"
/>
<div className={isStale ? "opacity-50 transition-opacity" : "transition-opacity"}>
<HeavyList query={deferredQuery} />
</div>
</div>
);
}O que isso demonstra:
query atualiza instantaneamente a cada pressionamento de tecla, mantendo a entrada responsivadeferredQuery fica para trás, então HeavyList re-renderiza com menor prioridadeReact.memo em HeavyList é essencial - sem ele, o componente re-renderiza com query de qualquer maneiradeferredQuery !== queryuseDeferredValue aceita um valor e retorna uma cópia adiada dele| Parâmetro | Tipo | Descrição |
|---|---|---|
value | T | O valor que você deseja adiar |
initialValue | T (React 19) | Valor inicial opcional para a primeira renderização |
| Retorno | Tipo | Descrição |
|---|---|---|
deferredValue | T | A versão adiada do valor |
Adiar conteúdo do Suspense:
function App() {
const [query, setQuery] = useState("");
const deferredQuery = useDeferredValue(query);
return (
<>
<SearchInput value={query} onChange={setQuery} />
<Suspense fallback={<Skeleton />}>
<SearchResults query={deferredQuery} />
</Suspense>
</>
);
}Valor inicial do React 19 (evitar mostrar conteúdo desatualizado na montagem):
// Mostra resultados vazios inicialmente, depois preenche em baixa prioridade
const deferredItems = useDeferredValue(items, []);Combinando com transição para estado de carregamento:
const deferredQuery = useDeferredValue(query);
const isStale = deferredQuery !== query;
return (
<div>
{isStale && <p className="text-sm text-gray-400">Carregando...</p>}
<Results query={deferredQuery} />
</div>
);// O tipo é inferido do valor de entrada
const deferredQuery = useDeferredValue(query); // string
// React 19 com initialValue
const deferredItems = useDeferredValue<Item[]>(items, []);Esquecer React.memo - useDeferredValue só ajuda se o componente filho for memoizado. Caso contrário, o filho re-renderiza com o valor atual na primeira passagem de qualquer maneira. Correção: Envolva o filho caro com React.memo.
Não é adequado para limitar chamadas de API - useDeferredValue adia a renderização, não a mudança de valor em si. Ele não reduz o número de chamadas de fetch. Correção: Use debounce para chamadas de API; use useDeferredValue para desempenho de renderização.
Flash de conteúdo desatualizado - O valor adiado fica atrás do valor real, então os usuários veem conteúdo desatualizado brevemente. Correção: Mostre um indicador visual (opacidade, spinner) quando deferredValue !== value.
Apenas valores primitivos - Passar um novo objeto ou array a cada renderização anula o propósito, pois a comparação Object.is encontra um novo valor a cada vez. Correção: Memoize objetos ou arrays com useMemo antes de passá-los para useDeferredValue.
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
useTransition | Você controla quando a atualização do estado acontece e quer envolvê-la explicitamente | Você recebe o valor como uma prop e não pode controlar quando ele muda |
| Debouncing | Você quer reduzir o número de atualizações de estado ou chamadas de API | Você quer feedback instantâneo com renderização adiada |
| Virtualização | O gargalo é renderizar muitos nós DOM | O gargalo é computação, não contagem de DOM |
| Web Worker | Computação pesada deve ser movida completamente da thread principal | O trabalho é renderização React |
useDeferredValue vs. useTransition: useTransition envolve a atualização do estado; useDeferredValue envolve o consumo do valor. Use useDeferredValue quando você não controla a atualização do estado (por exemplo, ela vem de uma prop ou de um componente pai).
React.memo, o filho re-renderiza em cada renderização do pai com o valor atual, não o adiado.React.memo pula a re-renderização quando as props não mudaram, permitindo que o valor adiado fique para trás.useDeferredValue não oferece benefício de renderização.const deferredQuery = useDeferredValue(query);
const isStale = deferredQuery !== query;
return (
<div className={isStale ? "opacity-50" : ""}>
<Results query={deferredQuery} />
</div>
);useDeferredValue permite que o estado atualize imediatamente, mas adia quando o filho re-renderiza.useDeferredValue para desempenho de renderização.useDeferredValue compara valores com Object.is, que verifica a igualdade de referência.{} ou array [] criado durante a renderização sempre tem uma nova referência.useMemo antes de passá-los para useDeferredValue.debounce ou throttle no manipulador de entrada.useDeferredValue apenas ajuda com renderizações caras do React.// A primeira renderização usa [] em vez do array completo de itens
const deferredItems = useDeferredValue(items, []);useDeferredValue funciona com qualquer componente filho caro, não apenas aqueles habilitados para Suspense.// O tipo é inferido do valor de entrada
const deferredQuery = useDeferredValue(query); // string
// React 19 com initialValue
const deferredItems = useDeferredValue<Item[]>(items, []);useDeferredValue quando você recebe um valor que muda rapidamente como uma prop e não controla a atualização do estado.useTransition quando você controla o setter de estado e quer envolver a atualização explicitamente.Revisado por Chris St. John·Última atualização: 16 de jul. de 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥