> Как работать с DOM-элементами в React, используя рефы? (React)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Точка, Сбер

Стек: React

> Пример ответа

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

Основные способы создания и использования рефов:

  1. useRef (в функциональных компонентах): Самый распространённый способ. Создаётся объект рефа с помощью useRef(), который затем прикрепляется к JSX-элементу через атрибут ref. После монтирования компонента в ref.current будет находиться DOM-узел.

    JSX
    import { useRef, useEffect } from 'react';
    function MyComponent() {
    const inputRef = useRef(null);
    useEffect(() => {
    // Автоматический фокус на инпуте при монтировании
    if (inputRef.current) {
    inputRef.current.focus();
    }
    }, []);
    return <input ref={inputRef} type="text" />;
    }
  2. createRef (в классовых компонентах): Используется в классовых компонентах, создаётся в конструкторе.

    JSX
    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.inputRef = React.createRef();
    }
    componentDidMount() {
    this.inputRef.current.focus();
    }
    render() {
    return <input ref={this.inputRef} />;
    }
    }
  3. Callback refs: Более гибкий подход, когда реф задаётся функцией. Позволяет выполнять код при каждом изменении рефа (например, при смене дочернего элемента).

    JSX
    function MyComponent() {
    const measureRef = useCallback((node) => {
    if (node !== null) {
    console.log('Ширина элемента:', node.offsetWidth);
    }
    }, []);
    return <div ref={measureRef}>Измеряемый блок</div>;
    }

Важные моменты:

  • Рефы не должны использоваться для "декларативных" вещей, которые можно сделать через состояние и пропсы (например, скрытие/показ элемента). Их основная задача - императивное взаимодействие с DOM.

  • Для передачи рефа дочернему компоненту (например, кнопке из UI-библиотеки) используйте forwardRef.

  • Избегайте чрезмерного использования рефов - это нарушает реактивный поток данных.

Пример с forwardRef:

JSX
const FancyInput = React.forwardRef((props, ref) => {
return <input ref={ref} className="fancy" {...props} />;
});
function Parent() {
const inputRef = useRef();
useEffect(() => inputRef.current?.focus(), []);
return <FancyInput ref={inputRef} />;
}

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью