useRef и createRef — это два способа создания ссылок в React с разными областями применения:
// useRef в функциональном компоненте
const inputRef = useRef(null);
// createRef в классовом компоненте
this.inputRef = createRef();useRef и createRef — это инструменты для работы с DOM-элементами и хранения мутабельных значений в React! Они решают похожие задачи, но работают по-разному. 🔧
| Характеристика | useRef | createRef |
|---|---|---|
| Тип компонента | Функциональный | Классовый |
| Время жизни | Сохраняется между рендерами | Создаётся заново каждый раз |
| Производительность | Высокая | Ниже |
| Современность | Современный подход | Устаревший подход |
useRef создаёт мутабельный объект, который сохраняется между рендерами:
import { useRef, useEffect } from 'react';
function MyComponent() {
const inputRef = useRef(null);
const countRef = useRef(0);
useEffect(() => {
// Фокус на input
inputRef.current.focus();
}, []);
const handleClick = () => {
countRef.current += 1;
console.log(countRef.current); // Не вызывает ререндер
};
return (
<div>
<input ref={inputRef} />
<button onClick={handleClick}>Увеличить счётчик</button>
</div>
);
}createRef создаёт новый объект ссылки при каждом вызове:
import React, { Component, createRef } from 'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.inputRef = createRef();
this.countRef = createRef();
}
componentDidMount() {
// Фокус на input
this.inputRef.current.focus();
}
handleClick = () => {
console.log(this.inputRef.current.value);
};
render() {
return (
<div>
<input ref={this.inputRef} />
<button onClick={this.handleClick}>Получить значение</button>
</div>
);
}
}function Component() {
const ref = useRef(null); // Создаётся один раз
// ref.current всегда один и тот же объект
console.log(ref); // { current: null }
return <div ref={ref} />;
}class Component extends React.Component {
render() {
const ref = createRef(); // Создаётся при каждом рендере!
return <div ref={ref} />;
}
}
// Правильное использование в классе
class Component extends React.Component {
constructor(props) {
super(props);
this.ref = createRef(); // Создаётся один раз
}
render() {
return <div ref={this.ref} />;
}
}// useRef
function ScrollToTop() {
const topRef = useRef(null);
const scrollToTop = () => {
topRef.current?.scrollIntoView({ behavior: 'smooth' });
};
return (
<div>
<div ref={topRef}>Верх страницы</div>
<button onClick={scrollToTop}>Наверх</button>
</div>
);
}
// createRef
class ScrollToTop extends Component {
constructor(props) {
super(props);
this.topRef = createRef();
}
scrollToTop = () => {
this.topRef.current?.scrollIntoView({ behavior: 'smooth' });
};
render() {
return (
<div>
<div ref={this.topRef}>Верх страницы</div>
<button onClick={this.scrollToTop}>Наверх</button>
</div>
);
}
}// useRef для хранения значений без ререндера
function Timer() {
const [time, setTime] = useState(0);
const intervalRef = useRef(null);
const startTimer = () => {
intervalRef.current = setInterval(() => {
setTime(prev => prev + 1);
}, 1000);
};
const stopTimer = () => {
clearInterval(intervalRef.current);
};
return (
<div>
<p>Время: {time}</p>
<button onClick={startTimer}>Старт</button>
<button onClick={stopTimer}>Стоп</button>
</div>
);
}❌ Неправильно:
// createRef в render - создаётся заново!
class Component extends React.Component {
render() {
const ref = createRef();
return <div ref={ref} />;
}
}✅ Правильно:
// createRef в constructor
class Component extends React.Component {
constructor(props) {
super(props);
this.ref = createRef();
}
render() {
return <div ref={this.ref} />;
}
}Основные различия useRef и createRef:
Используйте useRef в современной разработке! 🚀