forwardRef() - это функция в React, которая позволяет передавать ссылки (refs) через компоненты. Обычно ссылки можно присоединять только к DOM-элементам или классовым компонентам, но с помощью forwardRef() можно передать ссылку через функциональный компонент.

import React, { forwardRef } from 'react';
 
// Функциональный компонент, который принимает ref
const MyInput = forwardRef((props, ref) => {
  return <input type="text" ref={ref} {...props} />;
});
 
// Родительский компонент
const ParentComponent = () => {
  const inputRef = React.useRef(null);
 
  const focusInput = () => {
    inputRef.current.focus();
  };
 
  return (
    <div>
      <MyInput ref={inputRef} />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
};
 
export default ParentComponent;
  1. forwardRef(): Эта функция принимает компонент и возвращает новый компонент, который может принимать ref в качестве второго аргумента.
  2. ref в forwardRef: Внутри компонента MyInputref передается непосредственно на <input> элемент. Это позволяет родительскому компоненту управлять этим элементом через ref.
  3. Использование ref в родительском компоненте: В ParentComponent создается ref с помощью useRef(), который затем передается в MyInput. Когда пользователь нажимает кнопку “Focus Input”, вызывается метод focus() на inputRef.current, что фокусирует <input> элемент.

Зачем это нужно?

  • Управление DOM-элементамиforwardRef() позволяет родительским компонентам управлять DOM-элементами, которые находятся внутри дочерних компонентов.
  • Передача ссылок через несколько уровней: Если у вас есть несколько вложенных компонентов, forwardRef() позволяет передавать ссылки через все эти уровни.

as React 19 && ref as prop

Начиная с React 19, теперь вы можете получить доступ к ref как к пропу для функциональных компонентов:

function MyInput({ placeholder, ref }) {
  return <input placeholder={placeholder} ref={ref} />;
}
 
//...
<MyInput ref={ref} />

Новые функциональные компоненты больше не будут нуждаться в forwardRef, и мы опубликуем codemod для автоматического обновления ваших компонентов для использования нового пропса ref. В будущих версиях мы планируем объявить forwardRef устаревшим и удалить его.

Примечание:

Ссылки, переданные классовым компонентам, не передаются как пропсы, так как они ссылаются на экземпляр компонента.

Мы добавили опцию initialValue в useDeferredValue:

function Search({deferredValue}) {
  // При первоначальном рендеринге значение будет ''.
  // Затем запланирован повторный рендеринг с deferredValue.
  const value = useDeferredValue(deferredValue, '');
  
  return (
    <Results query={value} />
  );
}

Когда предоставляется initialValueuseDeferredValue вернет его как значение для первоначального рендеринга компонента и запланирует повторный рендеринг в фоновом режиме с возвращенным deferredValue.

Очищающие функции для refs

Теперь мы поддерживаем возвращение очищающей функции из колбэков ref:

<input
  ref={(ref) => {
    // ref создан
 
    // НОВОЕ: возвращаем очищающую функцию для сброса
    // ref, когда элемент удаляется из DOM.
    return () => {
      // очистка ref
    };
  }}
/>

Когда компонент размонтируется, React вызовет очищающую функцию, возвращенную из колбэка ref. Это работает для DOM refs, refs к классовым компонентам и useImperativeHandle.

Примечание:
Ранее React вызывал функции ref с null при размонтировании компонента. Если ваш ref возвращает очищающую функцию, React теперь пропустит этот шаг.

В будущих версиях мы объявим устаревшим вызов refs с null при размонтировании компонентов.

Из-за введения очищающих функций ref, возвращение чего-либо другого из колбэка ref теперь будет отклонено TypeScript. Исправление обычно заключается в прекращении использования неявных возвратов, например:

- <div ref={current => (instance = current)} />
+ <div ref={current => {instance = current}} />

Исходный код возвращал экземпляр HTMLDivElement, и TypeScript не мог определить, была ли это предполагаемая очищающая функция или вы не хотели возвращать очищающую функцию.

Вы можете автоматически исправить этот шаблон с помощью no-implicit-ref-callback-return.


Назад