forwardRef: expor uma ref através de um componente
As ref não são passadas como uma prop normal. Se você quer que um componente
pai obtenha uma referência a um nó dentro de um componente filho, esse filho
deve reencaminhar a ref com React.forwardRef:
const Input = React.forwardRef(function Input(props, ref) {
return <input ref={ref} {...props} />;
});
function Formulario() {
const inputRef = React.useRef(null);
// inputRef.current apontará para o <input> real do filho
return <Input ref={inputRef} />;
}
useImperativeHandle: personalizar o que a ref expõe
Às vezes você não quer dar acesso ao nó DOM inteiro, mas apenas a algumas
ações concretas (uma mini-API imperativa). useImperativeHandle define
exatamente o que o pai verá através da ref:
const Campo = React.forwardRef(function Campo(props, ref) {
const inputRef = React.useRef(null);
React.useImperativeHandle(ref, () => ({
focar: () => inputRef.current.focus(),
limpar: () => { inputRef.current.value = ""; },
}));
return <input ref={inputRef} />;
});
// O pai pode chamar campoRef.current.focar() — e nada mais.
É um padrão excepcional: use-o apenas para ações imperativas reais (foco, scroll, reproduzir/pausar). Para dados, continue preferindo props e estado.
Hooks concorrentes: manter a UI responsiva
O React moderno pode interromper e priorizar renderizações. Dois hooks aproveitam isso para que o trabalho custoso não congele a interface:
useTransition
Marca uma atualização de estado como não urgente (uma transição). O React
a processa com baixa prioridade, deixando que as interações urgentes (digitar em
um input) respondam na hora. Além disso, dá um isPending para mostrar um
indicador de carregamento:
const [isPending, startTransition] = useTransition();
function buscar(texto) {
setTexto(texto); // urgente: o input se atualiza já
startTransition(() => {
setResultados(filtrar(texto)); // não urgente: pode esperar/ser interrompido
});
}
useDeferredValue
Recebe um valor e devolve uma versão "atrasada" dele. Enquanto chega um valor novo, o React pode continuar mostrando o anterior, evitando recalcular uma lista pesada a cada tecla pressionada:
const consultaDiferida = useDeferredValue(consulta);
// A lista cara é filtrada com consultaDiferida, não com consulta.
Ambos perseguem o mesmo: que digitar ou clicar se sinta fluido mesmo que haja uma renderização cara em segundo plano.
useId: identificadores únicos e estáveis
React.useId gera um id único e estável para o componente, idêntico no
servidor e no cliente (chave para evitar erros de hidratação). Seu uso estrela é
a acessibilidade: vincular um <label> com seu <input>.
function Campo() {
const id = React.useId();
return (
<div>
<label htmlFor={id}>Nome</label>
<input id={id} />
</div>
);
}
Assim você não precisa inventar ids na mão (que colidiriam se o componente for
usado várias vezes na página). Nunca use useId para gerar keys de listas:
é para ids de elementos do DOM.
No exercício de código você praticará
React.useId(síncrono e validável). Os hooks concorrentesuseTransitioneuseDeferredValuesão avaliados nos questionários, já que seu efeito depende do agendador assíncrono do React.