← Назад к вопросам

Можно ли технически положить DOM node в useState?

1.3 Junior🔥 81 комментариев
#Браузер и сетевые технологии

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Хранение DOM-узлов в useState: Технические детали

Технически возможно поместить DOM-узел в состояние через useState, однако это не рекомендуется и может привести к множеству проблем. Давайте разберёмся почему.

Что произойдёт если поместить DOM node в useState?

import { useState, useEffect } from 'react';

function ElementStorage() {
  const [element, setElement] = useState(null);

  useEffect(() => {
    const div = document.getElementById('my-div');
    setElement(div); // Технически сработает
  }, []);

  return (
    <div>
      <div id="my-div">Целевой элемент</div>
      <button onClick={() => {
        if (element) {
          console.log(element.textContent); // Отобразит текст
        }
      }}>
        Читать элемент
      </button>
    </div>
  );
}

Да, такой код технически работает. React не выбросит ошибку и DOM-узел сохранится в state.

Почему это плохая идея?

1. Re-renders и потеря ссылки

// ПРОБЛЕМА: При каждом re-render ссылка может измениться
function BadExample() {
  const [element, setElement] = useState(null);

  // Этот обработчик вызывается при КАЖДОМ re-render
  const handleClick = () => {
    const newElement = document.querySelector('div');
    setElement(newElement); // Новый re-render -> новая ссылка
    // Может привести к infinite loop
  };

  return <button onClick={handleClick}>Клик</button>;
}

2. Проблемы сборки мусора (Memory Leak)

function MemoryLeakExample() {
  const [element, setElement] = useState(null);

  useEffect(() => {
    const div = document.querySelector('div');
    setElement(div); // Ссылка хранится в state
    
    // Если элемент удалится из DOM, но останется в state,
    // он не будет удалён сборщиком мусора
    // Это особенно критично для больших элементов с слушателями событий
  }, []);

  // Если компонент размонтируется, ссылка остаётся в памяти
  return null;
}

3. React не может отслеживать изменения DOM

function OutOfSync() {
  const [element, setElement] = useState(null);

  useEffect(() => {
    setElement(document.getElementById('target'));
  }, []);

  // Если внешний код удалит элемент из DOM
  // React не узнает об этом
  const handleDelete = () => {
    if (element) {
      element.remove(); // DOM изменён
      // Но state всё ещё хранит мёртвую ссылку!
    }
  };

  return (
    <div>
      <div id="target">Элемент</div>
      <button onClick={handleDelete}>Удалить из DOM</button>
    </div>
  );
}

Правильный подход: useRef

Для хранения ссылок на DOM-узлы используй useRef, а не useState:

import { useRef, useEffect } from 'react';

function CorrectWay() {
  const elementRef = useRef(null);

  useEffect(() => {
    // ref.current всегда указывает на актуальный элемент
    if (elementRef.current) {
      console.log(elementRef.current.textContent);
    }
  }, []);

  const handleFocus = () => {
    elementRef.current?.focus();
  };

  return (
    <div>
      <input ref={elementRef} type="text" />
      <button onClick={handleFocus}>Установить фокус</button>
    </div>
  );
}

Различия между useState и useRef для DOM

АспектuseStateuseRef
Re-render при измененииДаНет
Синхронизация с ReactДаНет
ПредназначениеДанные состоянияСсылки на DOM/значения
ПроизводительностьХуже для DOMЛучше для DOM
Отслеживание измененийАвтоматическоеНужно вручную

Когда всё же использовать state для DOM

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

function TextContent() {
  const [text, setText] = useState('');

  useEffect(() => {
    const element = document.getElementById('display');
    if (element) {
      // Сохраняем не сам элемент, а его СОДЕРЖИМОЕ
      setText(element.textContent);
    }
  }, []);

  return <p>{text}</p>; // Используем данные, не сам элемент
}

Основное правило: хранишь данные -> useState, нужна ссылка на DOM -> useRef. Это фундаментальное различие в React-архитектуре, которое обеспечивает предсказуемость и производительность приложения.