Přeskočit na obsah

ref jako obyčejný prop: sbohem, forwardRef

V React 19 dostávají funkční komponenty ref přímo v props. A ref callbacky konečně umí vrátit cleanup funkci.

Autor
Jan Jarčík
Publikováno
Doba čtení
2 min čtení
Aktualizováno
SdíletXLinkedInBluesky

forwardRef byl roky nutné zlo: chcete-li, aby vaše <Input> komponenta přijala ref, museli jste ji obalit a smířit se s ošklivějšími typy. React 19 to ruší — ref je u funkčních komponent běžný prop.

Před a po

TSX
// React 18
const Input = forwardRef<HTMLInputElement, InputProps>(function Input(props, ref) {
  return <input ref={ref} {...props} />;
});
TSX
// React 19
function Input({ ref, ...props }: InputProps & { ref?: React.Ref<HTMLInputElement> }) {
  return <input ref={ref} {...props} />;
}

Komponenta je obyčejná funkce, DevTools ukazují správné jméno a typy jsou čitelné. Pokud props typujete přes React.ComponentProps<"input">, ref už v nich je.

forwardRef zatím funguje, ale v budoucí verzi bude označený jako zastaralý. Pro migraci existuje codemod.

Cleanup v ref callbacku

Ref callback se dřív volal s null při odpojení. Teď z něj můžete vrátit cleanup funkci — přesně jako z efektu:

TSX
<div
  ref={(node) => {
    const observer = new ResizeObserver(([entry]) => {
      setWidth(entry.contentRect.width);
    });
    observer.observe(node);
    return () => observer.disconnect();
  }}
/>

Vrátíte-li cleanup, React při odpojení callback s null nevolá. Pozor u TypeScriptu: implicitní návrat (ref={(n) => (instance = n)}) teď neprojde typovou kontrolou — použijte složené závorky.

Kdy sáhnout po useImperativeHandle

Pokud nechcete vystavit celý DOM uzel, ale jen pár metod (focus, scrollToBottom), kombinujte ref prop s useImperativeHandle(ref, () => ({ … })). Funguje stejně jako dřív — jen bez obalování.