website/docs/react/refs.md
React allows you to grab the instance of an element or component with refs.
useRef hook {#toc-refs-in-functional-components}Inside a component, refs are created with the useRef hook:
import {useRef} from 'react';
import * as React from 'react';
component MyComponent() {
const buttonRef = useRef<null | HTMLButtonElement>(null);
return <button ref={buttonRef}>Toggle</button>;
}
Note that useRef wraps the ref value in an object with a current property. This must be
reflected in the type of anything accepting the ref value.
The type useRef returns is React.RefObject<T>. Use it to annotate anything that accepts the ref object, such as a helper that reads current:
import {useRef} from 'react';
import * as React from 'react';
function focusInput(ref: React.RefObject<null | HTMLInputElement>) {
if (ref.current != null) {
ref.current.focus();
}
}
component MyComponent() {
const inputRef = useRef<null | HTMLInputElement>(null);
return <input ref={inputRef} onClick={() => focusInput(inputRef)} />;
}
ref.current {#toc-reading-ref-current}The current property starts out null and is only populated after the element mounts, so its type includes null. Refine it with a != null check before using it:
import {useRef} from 'react';
import * as React from 'react';
component MyComponent() {
const inputRef = useRef<null | HTMLInputElement>(null);
const focusInput = () => {
inputRef.current.focus(); // ERROR: `current` may be null
if (inputRef.current != null) {
inputRef.current.focus(); // OK: refined to non-null
}
};
return <input ref={inputRef} onClick={focusInput} />;
}
React.RefSetter {#toc-accepting-a-ref}To let a parent attach a ref to your component, add a ref parameter typed with React.RefSetter<T>, where T is the instance you expose. With Component Syntax this is just another parameter:
import {useRef} from 'react';
import * as React from 'react';
component FancyInput(ref: React.RefSetter<HTMLInputElement>) {
return <input ref={ref} />;
}
component Form() {
const inputRef = useRef<null | HTMLInputElement>(null);
return <FancyInput ref={inputRef} />;
}
You write the ref parameter the same way regardless of the React version you target; behind the scenes Component Syntax compiles it to a React.forwardRef call (React 18) or a plain ref prop (React 19). The ref must be a direct parameter, not nested in a rest parameter. See Ref Parameters for the full explanation.
Instead of a ref object, you can pass a function as a ref. React calls it with the element instance when it mounts, and with null when it unmounts, so the parameter type is T | null:
import * as React from 'react';
component MyComponent() {
const setButtonRef = (button: HTMLButtonElement | null) => {
if (button != null) {
button.focus();
}
};
return <button ref={setButtonRef}>Toggle</button>;
}
A ref parameter typed React.RefSetter<T> accepts both a ref object and a callback ref, so a component written with the pattern above works with either.
To name the type behind a ref without spelling it out, Flow provides two utilities:
React.ElementRef<typeof Component> gives the instance type a component exposes (for example HTMLInputElement for an 'input', or a class instance for a class component).React.RefOf<Component> gives the type of the current field on a component's ref prop, or void if it has none.React.RefSetter, React.RefObject, React.RefOf, React.ElementRef, and other built-in React types