forwardRef в React: когда и как его использовать

Система ref, доступная в React, позволяет вам, например, получать доступ к традиционным узлам DOM или другим компонентам и изменять их (а это означает, что вы не используете обычный поток данных). Это очень полезно, особенно когда вы хотите разобраться с каким-то конкретным случаем, например, сосредоточиться на полях ввода, анимации или просто обработке элементов. Однако, когда компоненты используются повторно и являются вложенными, возникают проблемы, поскольку сложно передавать ссылки через промежуточные уровни компонентов, но в этой статье мы покажем вам, как с этим справиться.

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

Эта функция передает ссылки через компонент для прямого доступа к дочернему компоненту или даже к элементу DOM. Она наиболее применима в тех случаях, когда структура компонента сложна, например, когда родительский компонент хочет управлять другими компонентами, расположенными значительно ниже дерева компонентов, или взаимодействовать с ними. Это полезно для заполнения этого пробела, не нарушая герметизацию компонентов.

По умолчанию атрибут ref используется для передачи элемента DOM непосредственно экземпляру компонента. Однако, если есть повторно используемый компонент, который не предоставляет доступ к внутреннему DOM напрямую, передать ref будет сложно. Функция направлена на решение этой проблемы, поскольку компоненты могут свободно передавать ссылку от родительского элемента к определенному узлу DOM или дочернему компоненту.

Почему forwardRef важен

Если функция отсутствует, ref будет передаваться только до компонента InputField, не позволяя родительскому элементу получить доступ к элементу input внутри. Это помогает преодолеть все эти проблемы и предотвращает потерю родительским компонентом возможности строго манипулировать вложенными узлами DOM с помощью forwardRef. Это может стать огромным преимуществом при разработке повторно используемых и управляемых компонентов, таких как конкретное поле ввода, в котором родительский элемент должен получить контроль над определенным действием, таким как фокусировка или изменение значения поля ввода. Это делает всю систему или состав компонентов более гибкими.

Как работает forwardRef

Когда компонент упаковывается с помощью этой функции, ссылка от родительского компонента сохраняется и передается дочернему компоненту в качестве второго аргумента. Этот процесс позволяет вам работать с дочерними элементами так, как если бы вы работали непосредственно с родительским компонентом. Например, если вы хотите, чтобы поле ввода принимало фокусировку при нажатии кнопки, функция позволяет передавать ссылку на ввод родительскому компоненту. При этом родительскому компоненту не требуется прямой доступ для запуска действий с вводом. Для дальнейшего анализа вы можете ознакомиться с документацией React forwardRef.

Используя ссылки напрямую или используя forwardRef?

Вы, наверное, догадались, что прямое использование ссылок в компоненте - это просто замечательно; вам нужно управлять элементами внутри одного и того же компонента. Однако одним из недостатков является то, что становится все труднее управлять дочерними компонентами без forwardRef, и, следовательно, большая гибкость приложения может стать проблемой.

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

Механика движения вперед

Функция принимает компонент в качестве аргумента и возвращает новый компонент, который может получать ссылку от своего родительского компонента. Это позволяет отображать ссылку на дочерний компонент, чтобы родительский компонент мог взаимодействовать с ним в режиме реального времени. Например, мы используем функцию для обертывания пользовательского компонента InputField, который включает в себя элемент ввода HTML; таким образом, родительский компонент может напрямую обращаться к DOM-узлу ввода.

import React, { forwardRef } from "react";

// Define the InputField component and wrap it with forwardRef
const InputField = forwardRef((props, ref) => {
  return <input type="text" ref={ref} {...props} />;
});

В приведенном выше примере функция forwardRef ожидает один аргумент: функциональный компонент. Теперь эта функция получает два параметра:

    props: Здесь вы увидите все, что было передано в InputField в качестве props родительским компонентом. Для этого {... props} передает все props в элемент <input>, указанный выше. ref: Этот параметр изначально используется с элементом input в InputField и в основном указывает на элементы. Как только ref передается элементу <input> (ref={ref}), родительский компонент получает полный контроль над этим дочерним элементом.

Использование функции, описанной выше, помогает напрямую перейти от родительской ссылки к элементу ввода HTML в указанном поле.

Пример использования родительского компонента

Параметр forwardRef используется, когда родительский элемент хочет получить доступ к собственному DOM-узлу дочернего компонента. В этом случае ParentComponent использует его для доступа к полю ввода, на котором он устанавливает фокус. Теперь давайте рассмотрим пример того, как родительский элемент может использовать InputField с функцией для управления элементом ввода.

import React, { useRef } from "react";

const ParentComponent = () => {
  // Create a ref using useRef
  const inputRef = useRef(null);

  // Function to focus the input
  const handleFocus = () => {
    if (inputRef.current) {
      inputRef.current.focus();
 }
 };

  return (
    <div>
      <InputField ref={inputRef} placeholder="Type something here..." />
      <button onClick={handleFocus}>Focus Input</button>
    </div>
 );
};

В приведенном выше:

    Перехватчик useRef создает переменную ref (inputRef) в компоненте ParentComponent. Затем эта ссылка перенаправляется в InputField, так что при вызове обработчика нажатия кнопки onClick он вызывает handleFocus. Это позволяет сфокусировать элемент ввода.

Компонент возвращает входной заполнитель “Type то here…âÂ, €Ќ ниже входного, есть кнопка с меткой “Focus вход.âÂ, €Ќ При нажатии на кнопку поле ввода фокусируется с помощью функции handleFocus. Далее в статье мы дадим более подробные объяснения и покажем, как правильно выводить данные.

Распространенные варианты использования forwardRef

Роль этой функции проявляется в нескольких ситуациях, когда родительский компонент манипулирует элементами внутреннего компонента. Описанный выше подход хорош для создания сложных элементов пользовательского интерфейса и элементов многократного использования, которые могут извлечь выгоду из прямого рабочего процесса с определенными дочерними элементами. В этом разделе давайте более подробно рассмотрим распространенные варианты использования.

Пользовательские компоненты ввода

Он также широко используется в нескольких элементах пользовательского ввода, которые могут включать текстовые поля, выпадающие списки или флажки. Если вы собираетесь создавать повторно используемые компоненты ввода, они часто используются для работы с этими полями. Например, фокусировка на вводимых данных при загрузке формы или удаление поля сразу после отправки. Функция позволяет родительскому компоненту напрямую обращаться к компоненту ввода, что относительно упрощает управление им. Теперь давайте рассмотрим пример.

// CustomInput component with forwardRef
const CustomInput = React.forwardRef((props, ref) => (
  <input type="text" ref={ref} {...props} />
));

Выше мы видим, что родительский элемент использует CustomInput, а затем работает, фокусируясь на элементе или очищая входные данные с помощью ref.

Повторно используемые компоненты пользовательского интерфейса

Эта функция полезна при создании повторно используемых компонентов пользовательского интерфейса, таких как кнопки, модальные элементы или формы, где родительский элемент хотел бы выполнять манипуляции с DOM. Например, давайте предположим, что модальный компонент часто нуждается в контроле над такими операциями, как открытие или закрытие модального элемента или концентрация на определенных полях только в модальном элементе. Функция forwardRef работает таким образом, что если вы предоставляете доступ к ключевым элементам MODAL через нее, это гарантирует, что родительский компонент сможет управлять этими действиями. Давайте рассмотрим пример ниже.

// ReusableModal component with forwardRef
const ReusableModal = React.forwardRef((props, ref) => (
  <div ref={ref} className="modal">
    {props.children}
  </div>
));

Что делает код: ReusableModal возвращает <div>, который отображает любой дочерний элемент, проходящий через props.children. React.forwardRef, позволяет компоненту получать ref, переданный от родительского, который затем применяется к этому <div>.

Как это работает:

    Благодаря этой функции родительский элемент может передать ref в ReusableModal, который указывает на <div> модального элемента. Это оставляет управление отображением модального элемента и другими параметрами в руках родительского элемента.

Использование props.children позволяет передавать любое содержимое через компонент, что позволяет повторно использовать его и для других целей.

С помощью этой функции модальный ключ <div> передается родительскому компоненту. Это позволяет вам выполнять прямые манипуляции с DOM, а также открывать, закрывать или фокусировать внимание, не оказывая влияния на внутренний код компонента.

Давайте посмотрим на другой пример, который описывает, как родительский элемент может использовать этот компонент.

const Parent = () => {
  const modalRef = React.useRef();

  const openModal = () => {
    modalRef.current.style.display = "block"; // Example to show modal
 };

  return (
    <div>
      <ReusableModal ref={modalRef}>
        <p>This is the modal content</p>
      </ReusableModal>
      <button onClick={openModal}>Open Modal</button>
    </div>
 );
};

Объяснение кода:

    Чтобы напрямую получить доступ к DOM-узлу MODAL, в Parent генерируется modalRef с помощью useRef(). Функция openModal устанавливает для modalRef.current.style.display значение block, что делает modal видимым. Эта функция запускается при нажатии кнопки "Открыть модальный режим", которая изменяет видимость модального режима непосредственно с помощью кнопки "Изменить".

И вот родительский компонент создает кнопку с надписью “Open Modal†ќ последующим экземпляр ReusableModal, которую несет текст “This является модальный контент.âÂ, €Ќ Этот режим изначально скрыт и может быть виден только при нажатии кнопки "Открыть режим". Он будет выглядеть примерно так, как показано ниже.

Find busted API calls

Capture HTTP payloads, track failed API calls and much more with console logs, errors and state management. Explore our Github repo and show your support by starring us.

Совместимость библиотеки и фреймворка

Многие сторонние библиотеки и фреймворки используют ссылки для получения доступа к элементам DOM. Существуют такие библиотеки, как валидаторы, фреймворки с возможностью перетаскивания или инструменты измерения DOM, которым может потребоваться прямой доступ к определенным элементам ваших компонентов. Можно использовать forwardRef, поскольку его легко интегрировать с этими библиотеками, предоставляя необходимые ссылки на элементы в ваших компонентах.

Например, у нас есть пользовательская кнопка, использующая компонент под названием DraggableButton, и мы хотим сделать ее доступной для перетаскивания с помощью сторонней библиотеки, которую мы назовем dragLibrary. Теперь эта библиотека потребует от вас ссылки на элемент DOM, с которым вы хотите работать, чтобы сделать его доступным для перетаскивания. Затем вы можете использовать эту функцию для передачи ссылки на кнопку, с помощью которой родительский компонент может ссылаться на функции drag-n-drop из dragLibrary.

import React, { forwardRef, useRef, useEffect } from "react";
// Hypothetical drag-and-drop library named 'dragLibrary'
import { enableDrag } from "dragLibrary";

// DraggableButton component wrapped with forwardRef
const DraggableButton = forwardRef((props, ref) => (
  <button ref={ref} {...props} className="draggable-button">
    {props.children}
  </button>
));

В приведенном выше примере компонент DraggableButton обернут функцией, которая позволяет родительскому элементу передавать ссылку на элемент <button>. Используя ref={ref} на <кнопке>, вы гарантируете, что элемент DOM будет доступен для вашего родительского компонента.

Вот пример использования ParentComponent вместе с этой ссылкой для интеграции кнопки с dragLibrary.

const ParentComponent = () => {
  const buttonRef = useRef();

  useEffect(() => {
    // Use the drag-and-drop library's function `enableDrag` to make the button draggable
    if (buttonRef.current) {
      enableDrag(buttonRef.current); // Enables dragging using dragLibrary
 }
 }, []);

  return <DraggableButton ref={buttonRef}>Drag Me</DraggableButton>;
};

Объяснение кода: В приведенном выше ParentComponent мы сначала используем useRef для создания buttonRef, а затем передаем его нашему компоненту DraggableButton, который затем перенаправляет ссылку на элемент <button>. Как только ParentComponent отрисует, он вызывает функцию enableDrag из dragLibrary, которая включает функцию перетаскивания с помощью кнопки "Перетащить меня". Это делает кнопку перетаскиваемой, позволяя пользователям перемещать ее по экрану. Выходные данные должны выглядеть так, как показано ниже.

Библиотеки анимации

Библиотеки анимации создают сложную и высокопроизводительную анимацию, работая непосредственно в DOM. forwardRef помогает легко интегрировать компоненты с библиотеками анимации, такими как Framer Motion и GSAP, для управления элементами DOM. Этот процесс полезен разработчикам, которые планируют разрабатывать захватывающие и интересные пользовательские интерфейсы, в которых отдельные компоненты перемещаются в зависимости от прокрутки или других действий.

Например, у вас может быть компонент, который анимирует элемент на экране, когда он появляется в окне просмотра. Используя forwardRef, вы можете открыть DOM-узел этого элемента. Это позволяет библиотеке анимации получить прямое управление.

// AnimatedBox component with forwardRef
const AnimatedBox = React.forwardRef((props, ref) => (
  <div ref={ref} className="animated-box">
    {props.children}
  </div>
));

Этот AnimatedBox, указанный выше, является компонентом, который взаимодействует с библиотекой анимации, где библиотеке может потребоваться взаимодействие с <div> для применения анимации. Ссылка на элемент <div>, указанный выше, отображается после реализации функции.

Теперь давайте подробнее рассмотрим, как AnimatedBox может использоваться родительским компонентом, который работает с библиотекой анимации (например, GSAP).

import { useRef, useEffect } from "react";
import gsap from "gsap";

const Parent = () => {
  const boxRef = useRef();

  useEffect(() => {
    // Use GSAP to animate the box when it mounts
    gsap.to(boxRef.current, { x: 100, duration: 2 });
 }, []);

  return (
    <AnimatedBox ref={boxRef}>
      <p>Animated content here</p>
    </AnimatedBox>
 );
};

Объяснение кода: Родительский компонент вызывает функцию useRef для создания boxRef, которая затем передается компоненту AnimatedBox. В рамках useEffect мы используем GSAP для перемещения элемента со ссылкой boxRef на 100 пикселей вправо на 2 секунды. Родительский компонент отображает AnimatedBox, содержащий HTML-тег <p>, который отображает текст "Анимированный контент здесь". Из-за заданной анимации GSAP этот контент перемещается по горизонтали при загрузке. Результат должен выглядеть так, как показано ниже.

Рекомендации по использованию forwardRef

К тому времени, как вы внедрили функцию React, вы уже на полпути к тому, чтобы сделать ваши компоненты более универсальными. Тем не менее, некоторые простые правила могут сделать код более удобным в обслуживании, а также упростить его просмотр другими пользователями. В этом разделе мы расскажем вам о нескольких вещах, которые следует иметь в виду при использовании React.

Избегайте чрезмерного использования ссылок

Несмотря на то, что ссылки, как было замечено, очень полезны, старайтесь избегать их чрезмерного использования, иначе компоненты будут тесно связаны с элементами DOM. Этот эффект затрудняет сохранение компонентов. Его использование должно быть ограничено компонентами, требующими прямого взаимодействия с DOM, такими как пользовательские компоненты ввода и анимация, или когда вы хотите работать со сторонними библиотеками. Вместо этого сосредоточьтесь на реквизитах и состояниях для большинства взаимодействий, поскольку с ними гораздо проще работать в экосистеме React.

Поведение компонента документа

Одна вещь, на которую следует обратить внимание в отношении этой функции, заключается в том, что вы должны добавить к компоненту хорошую документацию. Опишите, почему компонент использует ее и чего другим разработчикам следует ожидать от ссылки. Например, вы должны отметить, предоставляет ли ссылка доступ к определенному элементу в DOM (например, к полю ввода) или к определенным функциям в компоненте. Эта документация создается путем вставки комментариев в ваш код в тех местах, где вы считаете их необходимыми. Это поможет другим сотрудникам вашей нынешней или будущей команды научиться использовать тот или иной компонент и как он будет себя вести.

Комбинировать с помощью ручки useImperativeHandle

Крючок useImperativeHandle может быть полезен при управлении определенными объектами, которые будут отображаться через ref. По умолчанию часто доступен элемент DOM всего компонента, но вы можете захотеть предоставить доступ только к выбранным методам или свойствам, тогда useImperativeHandle предоставляет способ создания вашего API, который поможет сделать использование ref вашего компонента более безопасным и предсказуемым.

const CustomInput = React.forwardRef((props, ref) => {
  const inputRef = React.useRef();

  React.useImperativeHandle(ref, () => ({
    focusInput: () => inputRef.current.focus(),
 }));

  return <input ref={inputRef} {...props} />;
});

В приведенном выше примере родительскому компоненту предоставляется доступ только к focusInput, но не к другим свойствам элемента input. Вы можете найти более широкий контекст для этого в документации React's useImperativeHandle.

Используйте описательные имена переменных

При использовании этой функции вам следует убедиться, что вы придерживаетесь эффективного соглашения об именовании, обеспечивающего узнаваемость рецензента. Вы могли бы использовать такие имена, как ref, которые будут простыми, понятными и универсальными. Или вы могли бы вместо этого использовать modalRef или inputRef, которые, по крайней мере, указывают, для чего должна использоваться ссылка. Этот метод именования позволяет разработчикам легче оценить ваши намерения и использование ссылки в вашем компоненте. Давайте возьмем, к примеру, приведенный ниже стиль именования.

const CustomButton = React.forwardRef((props, buttonRef) => (
  <button ref={buttonRef} {...props}>
 Click me
  </button>
));

Такое имя, как buttonRef, используемое выше, будет лучшим выбором по сравнению с простым использованием "REF". Это потому, что легко заметить, что оно ссылается на элемент button.

Примеры эффективного использования forwardRef

Мы привели несколько примеров того, когда вам следует использовать эту функцию, но как извлечь из нее максимальную пользу? В этом разделе мы покажем несколько практических примеров того, как вы можете использовать ее для создания гибких компонентов.

Базовый компонент ввода с функцией forwardRef

Как уже упоминалось, базовые компоненты ввода являются одним из наиболее распространенных вариантов использования этой функции. Она позволяет создавать компоненты, которые могут повторно использоваться и вызываться родительским компонентом с помощью DOM-узла поля ввода, например, для фокусировки, очистки или проверки правильности полей ввода. Для этого вы создадите пользовательский компонент INPUT, который обертывает стандартный элемент ввода HTML. Функция позволяет родительскому компоненту передавать ссылку и присоединять ее к элементу <input>.

import React, { forwardRef } from "react";

// Create a reusable input component with `forwardRef`
const CustomInput = forwardRef((props, ref) => (
  <input type="text" ref={ref} {...props} />
));

export default CustomInput;

CustomInput использует forwardRef для обработки ссылок, приведенных выше. Ref - это второй аргумент (после props), передаваемый элементу <input>. Вот почему атрибут ref в <input> позволяет родительским компонентам получать ссылки на элементы DOM, на которые они влияют. И этот ввод очень удобен для повторного использования и гибок, потому что мы передаем {реквизит}.

Возникает следующий логичный вопрос: как родительский компонент сможет использовать наш пользовательский компонент ввода? Давайте рассмотрим, например, приведенный ниже пример кода, если нажата кнопка и вы хотите, чтобы родительский компонент сосредоточился на поле ввода.

import React, { useRef } from "react";
import CustomInput from "./CustomInput";

const FormComponent = () => {
  // Create a ref for the CustomInput component
  const inputRef = useRef();

  // Function to focus the input field when called
  const focusInput = () => {
    if (inputRef.current) {
      inputRef.current.focus();
 }
 };

  return (
    <div>
      {/* Use CustomInput and pass the ref */}
      <CustomInput ref={inputRef} placeholder="Enter text here" />
      <button onClick={focusInput}>Focus Input</button>
    </div>
 );
};

export default FormComponent;

Объяснение кода: Мы используем useRef для генерации ссылки с именем inputRef с помощью FormComponent, которая затем передается в CustomInput. Функция focusInput запускается при нажатии кнопки. Сначала он проверяет, доступен ли файл inputRef.current, и если да, то вызывает функцию focus() для установки в поле ввода. В FormComponent оказывает CustomInput с заполнителем “Enter текст hereâÂ, €ќ и кнопку: â€ввода ÂœFocus.âÂ, €Ќ Когда пользователь нажимает на кнопку, фокус перемещается в область поля ввода, чтобы он мог немедленно начать печатать, как показано на рисунке ниже.

Кнопочный компонент с анимированной Ссылкой

Другим примером является создание компонента кнопки, который должен отображать анимацию при каждом нажатии на нее. Здесь функция предоставляет доступ к узлу DOM, чтобы вы могли использовать различные анимации и другие визуальные эффекты.

import React, { forwardRef } from "react";

// Define an animated button component with `forwardRef`
const AnimatedButton = forwardRef((props, ref) => {
  const handleClick = () => {
    if (ref && ref.current) {
      ref.current.classList.add("animate");
      setTimeout(() => ref.current.classList.remove("animate"), 300);
 }
 };

  return (
    <button ref={ref} onClick={handleClick} {...props}>
      {props.children}
    </button>
 );
});

export default AnimatedButton;

В приведенном выше случае ссылка передается в AnimatedButton через forwardRef, прикрепленный к элементу <button>. Класс анимации добавляется с помощью handleClick для кнопки, так что при нажатии анимации требуется 300 мс, прежде чем она будет сброшена при следующем нажатии.

Затем родительский компонент может перейти к ссылке на AnimatedButton, которая может вызвать анимационный щелчок.

import React, { useRef } from "react";
import AnimatedButton from "./AnimatedButton";

const PageComponent = () => {
  const buttonRef = useRef();

  return (
    <div>
      <AnimatedButton ref={buttonRef}>Click Me</AnimatedButton>
    </div>
 );
};

export default PageComponent;

Объяснение кода:

В PageComponent он создает ссылку (buttonRef) с помощью useRef и передает ее компоненту AnimatedButton. Эту ссылку можно использовать в AnimatedButton для добавления анимации или эффектов к элементу button. Анимированная кнопка с надписью "Нажмите на меня" отображается с помощью PageComponent. Если анимированная кнопка содержит анимацию, такую как эффекты при нажатии или наведении курсора, они будут применены к кнопке после ее отображения. Ниже вы можете найти пример того, как это выглядит.

Интеграция forwardRef с формами

При использовании с формами это полезно для разработки элементов ввода, которыми можно управлять через родительскую форму. Например, мы указали, как функция может фокусировать или очищать поля ввода, когда это необходимо. В этом случае это позволяет осуществлять дальнейший контроль, указывая, что ref передает родительскому элементу через useImperativeHandle. Первый шаг обычно включает в себя определение элемента FormInput. Этот компонент будет использовать функцию для приема ссылки и useImperativeHandle для передачи определенных функций (таких как очистка и фокусировка ввода в родительской форме).

import React, { forwardRef, useImperativeHandle, useRef } from "react";

// Define a form input component with focus and clear functionalities
const FormInput = forwardRef((props, ref) => {
  const inputRef = useRef();

  // Define the functionality exposed to the parent via `useImperativeHandle`
  useImperativeHandle(ref, () => ({
    focusInput: () => inputRef.current.focus(),
    clearInput: () => (inputRef.current.value = ""),
 }));

  return <input ref={inputRef} {...props} />;
});

export default FormInput;

Приведенная выше форма ввода окружает элемент <input> и принимает ссылку через forwardRef. Для элемента <input> в компоненте ссылка (inputRef) присваивается с помощью useRef. В свою очередь, useImperativeHandle изменяет эту ссылку, чтобы предоставить родительскому компоненту доступ только к двум функциям (focusInput и clearinput).

А теперь давайте попробуем использовать FormInput в родительском компоненте формы. Здесь родительские элементы будут управлять вводом (фокусировкой и очисткой) с помощью открытой функции useImperativeHandle.

import React, { useRef } from "react";
import FormInput from "./FormInput";

const FormComponent = () => {
  // Create a ref for the FormInput component
  const inputRef = useRef();

  // Function to focus the input field
  const handleFocus = () => {
    inputRef.current.focusInput();
 };

  // Function to clear the input field
  const handleClear = () => {
    inputRef.current.clearInput();
 };

  return (
    <div>
      <FormInput ref={inputRef} placeholder="Enter name" />
      <button onClick={handleFocus}>Focus Input</button>
      <button onClick={handleClear}>Clear Input</button>
    </div>
 );
};

export default FormComponent;

Объяснение кода: В FormComponent, приведенном выше, inputRef передается в FormInput в качестве ссылки. Это делается для того, чтобы FormComponent мог вызывать определенные методы поля ввода в useImperativeHandle. Функция handleFocus вызывает функцию focusInput, которая при нажатии кнопки "Focus Input" фокусирует поле ввода. С другой стороны, handleClear очищает поле ввода с помощью clearInput при каждом нажатии кнопки "Очистить ввод", как показано ниже.

Вывод

Создание чистых и повторно используемых компонентов в React, обеспечивающих контролируемый доступ к DOM, возможно с помощью forwardRef. При правильном использовании это сделает компонент более универсальным и позволит родительским элементам напрямую подключаться к дочерним элементам. Если вы имеете дело с такими необходимыми функциями, как пользовательский ввод, анимированные кнопки или сложные взаимодействия с формами, это будет идеальным решением. Однако стоит отметить, что простая реализация этой функции - не единственный аспект, который следует учитывать. Вам следует ознакомиться с рекомендациями по ее использованию, чтобы улучшить свой код и уменьшить избыточность в больших приложениях. Наконец, вы можете ознакомиться со ссылочными значениями React в документации refs для получения дополнительной информации о связи функции с ref.