Рефы
React позволяет получить экземпляр элемента или компонента с помощью рефов.
Рефы с хуком useRef
Внутри компонента рефы создаются с помощью хука useRef:
import {useRef} from 'react';
import * as React from 'react';
component MyComponent() {
const buttonRef = useRef<null | HTMLButtonElement>(null);
return <button ref={buttonRef}>Toggle</button>;
} Обратите внимание: useRef оборачивает значение рефа в объект со свойством current. Это необходимо учитывать в типе всего, что принимает значение рефа.
Тип, который возвращает useRef, — это React.RefObject<T>. Используйте его для аннотации всего, что принимает объект рефа, например вспомогательной функции, которая читает 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
Изначально свойство current имеет значение null и заполняется только после монтирования элемента, поэтому его тип включает null. Перед использованием проверьте его с помощью != null:
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
Чтобы родительский компонент мог прикрепить реф к вашему компоненту, добавьте параметр ref с типом React.RefSetter<T>, где T — это экземпляр, который вы предоставляете. В синтаксисе компонентов это просто ещё один параметр:
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} />;
} Параметр ref записывается одинаково независимо от версии React, для которой вы разрабатываете; за кулисами синтаксис компонентов компилирует его в вызов React.forwardRef (React 18) или обычное свойство ref (React 19). Реф должен быть непосредственным параметром, а не вложенным в параметр rest. Полное объяснение см. в разделе «Параметры рефа».
Рефы-колбэки
Вместо объекта рефа можно передать функцию в качестве рефа. React вызывает её с экземпляром элемента при его монтировании и со значением null при размонтировании, поэтому тип параметра — 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>;
} Параметр ref с типом React.RefSetter<T> принимает как объект рефа, так и реф-колбэк, поэтому компонент, написанный по описанному выше шаблону, работает с обоими вариантами.
Получение типов рефов
Чтобы указать тип рефа, не расписывая его вручную, Flow предоставляет две утилиты:
-
React.ElementRef<typeof Component>возвращает тип экземпляра, который предоставляет компонент (например,HTMLInputElementдля'input'или экземпляр класса для классового компонента). -
React.RefOf<Component>возвращает тип поляcurrentв свойствеrefкомпонента илиvoid, если такого поля нет.
См. также
-
Типы React —
React.RefSetter,React.RefObject,React.RefOf,React.ElementRefи другие встроенные типы React - Параметры рефа — как синтаксис компонентов компилирует параметр рефа
- Функциональные и классовые компоненты — типизация классовых компонентов, включая их рефы
© 2013–present Facebook Inc.
Licensed under the MIT License.
https://flow.org/en/docs/react/refs