Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как хранятся Ref элементы в React
Ref (referencias) — это специальный механизм в React для прямого доступа к DOM элементам или инстансам компонентов. Это один из немногих способов «выйти из React» и работать с DOM напрямую.
Создание Ref
1. useRef хук (для функциональных компонентов)
import { useRef } from react;
function TextInput() {
const inputRef = useRef(null);
const handleClick = () => {
inputRef.current.focus(); // Доступ к DOM элементу
};
return (
<>
<input ref={inputRef} type="text" />
<button onClick={handleClick}>Focus Input</button>
</>
);
}
2. React.createRef (для классовых компонентов)
class TextInput extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
handleClick = () => {
this.inputRef.current.focus();
};
render() {
return (
<>
<input ref={this.inputRef} type="text" />
<button onClick={this.handleClick}>Focus</button>
</>
);
}
}
Что находится в ref.current
const ref = useRef(null);
// Для DOM элементов
<div ref={ref}>Hello</div>;
// ref.current содержит DOM node
console.log(ref.current); // <div>Hello</div>
console.log(ref.current.textContent); // "Hello"
// Для компонентов с forwardRef
const MyComponent = forwardRef((props, ref) => {
return <input ref={ref} />;
});
const inputRef = useRef(null);
<MyComponent ref={inputRef} />;
// inputRef.current содержит инстанс компонента
Внутреннее хранение Ref
React хранит Ref как часть фибры (fiber) — внутренней структуры, которая отслеживает компонент и его DOM.
// Упрощённое представление внутренней структуры:
// React Fiber для компонента выглядит примерно так:
const fiber = {
type: MyComponent,
ref: { current: null }, // Вот где хранится Ref!
hooks: [ /* хуки useRef, useState и т.д. */ ],
dom: null,
};
// После рендера DOM элемента:
fiber.ref.current = actualDOMElement;
Инициализация и обновление
// useRef инициализируется один раз
const ref = useRef(initialValue);
// ref = { current: initialValue }
// Значение ref НЕ вызывает re-render при изменении
ref.current = newValue; // Компонент не перерендерится!
// Это отличает useRef от useState:
const [value, setValue] = useState(initialValue);
// setValue() запускает re-render
Различие между useRef и переменной
// ❌ Неправильно — переменная пересоздаётся при каждом рендере
function Component() {
let ref = { current: null };
// ref пересоздаётся при каждом рендере!
}
// ✅ Правильно — useRef создаётся один раз
function Component() {
const ref = useRef(null);
// ref существует между рендерами
}
Жизненный цикл Ref
function Component() {
const ref = useRef(null);
useEffect(() => {
// Здесь ref уже содержит DOM элемент
console.log(ref.current); // <input />
return () => {
// Cleanup — ref может быть null
};
}, []);
// Во время рендера ref может быть null
console.log(ref.current); // null (пока рендер не завершён)
return <input ref={ref} />;
}
Практические примеры
Управление фокусом:
function SearchInput() {
const inputRef = useRef(null);
const handleSearch = () => {
inputRef.current.focus();
};
return (
<>
<input ref={inputRef} type="text" />
<button onClick={handleSearch}>Search</button>
</>
);
}
Доступ к методам DOM:
function VideoPlayer() {
const videoRef = useRef(null);
const play = () => videoRef.current.play();
const pause = () => videoRef.current.pause();
return (
<>
<video ref={videoRef}>
<source src="movie.mp4" />
</video>
<button onClick={play}>Play</button>
<button onClick={pause}>Pause</button>
</>
);
}
Работа с библиотеками (jQuery, D3):
function D3Chart() {
const svgRef = useRef(null);
useEffect(() => {
if (svgRef.current) {
// Использование D3 с реальным DOM элементом
d3.select(svgRef.current)
.append("circle")
.attr("r", 40);
}
}, []);
return <svg ref={svgRef} />;
}
Важные моменты
- Не переусложняй: Ref нужен только для особых случаев (фокус, медиа, интеграция с третьими библиотеками)
- Избегай доступа к Ref во время рендера: это нарушает React парадигму
- forwardRef для пробрасывания Ref в компоненты: нестандартный проп, требует явной пробраски
- Ref НЕ вызывает re-render, в отличие от state
Краткий вывод: Ref — это безопасный способ прямого доступа к DOM, но используй его осторожно. В 90% случаев есть React способ сделать то же самое.