Хук useRef для работы с рефами в React
На этом уроке мы поработаем с рефами. Для
наглядности давайте разберем работу
хука useRef
в сравнении с хуком
useState
.
Давайте создадим компонент с кнопкой:
return (
<div>
<button>
state click
</button>
</div>
);
Импортируем в компонент useState
:
import { useState } from 'react';
И заведем стейт state
:
const [state, setState] = useState(0);
А сейчас сделаем так, чтобы по клику на
кнопку наш state
увеличивался бы
на 1
. Значение стейта будем
выводить прямо в тексте кнопки:
<button onClick={handleStateClick}>
state click: {state}
</button>
Опишем функцию для обработки клика
по кнопке handleStateClick
:
function handleStateClick() {
setState(state + 1);
}
Понажимаем кнопочку и увидим, как растет значение стейта.
А сейчас давайте создадим компонент
App
, но используя не стейт,
а реф.
Для начала, импортируем в компонент
useRef
:
import { useRef } from 'react';
И заведем реф ref
. Своим
результатом хук useRef
возвращает
объект рефа с единственным свойством
current
, которое нас и будет
интересовать в дальнейшем. Установим
его начальное значение в 0
:
const ref = useRef(0);
Навесим на кнопочку обработчик
клика. Помните, что мы должны
читать/изменять не сам ref
,
а его свойство current
:
<button onClick={handleRefClick}>
ref click: {ref.current}
</button>
Добавим функцию для обработки клика
по нашей кнопке. Здесь мы будем
увеличивать current
на 1
,
как и в предыдущем примере со стейтом. В
отличие от стейта, где требуется функция
setState
для изменения его значения,
со свойством рефа мы работаем напрямую:
function handleRefClick() {
ref.current = ref.current + 1;
}
Теперь понажимаем нашу кнопку. И что же
мы видим? При клике по ней, как у нас
был изначально 0
, так он и не
меняется.
Вы, конечно, можете начать сомневаться
в том, что значение вообще меняется.
Давайте это проверим. Для этого в функции
обработчика клика добавим еще строчку кода
с выводом значения current
в консоль:
function handleRefClick() {
ref.current = ref.current + 1;
console.log('ref click: ' + ref.current);
}
А сейчас, открыв консоль в браузере, снова покликаем по кнопке и убедимся, что значение действительно меняется при каждом клике и никакого обмана нет.
Теперь мы видим, что в отличие от стейта,
изменение значения рефа не вызывает
рендеринг компонента. Поэтому мы каждый
раз в тексте кнопки видим начальное
значение 0
.
Таким образом, если ваши данные используются для рендеринга, то храните их в стейте, а если вам не нужен рендеринг, в таком случае использование рефов может стать более эффективным.
Пусть в вашем компоненте есть абзац с
текстом 'text'
и кнопка. Сделайте
так, чтобы каждый раз по клику на кнопку
в конец текста абзаца добавлялся
восклицательный знак. Сделайте это
с помощью стейта.
Создайте компонент App, но вместо стейта теперь используйте реф. Убедитесь, что при нажатии кнопки текст абзаца не будет меняться. Добавьте также вывод текста абзаца в консоль, откройте ее и убедитесь, что на самом деле текст меняется.