Хук useRef для работы з рэфамi ў React

На гэтым уроку мы папрацуем з рэфамі. Для нагляднасці давайце разбярэм работу хука useRef у параўнанні з хукам useState.

Давайце створым компонент з кнопкай:

App.jsxreturn (
  <div>
    <button>
      state click
    </button>
  </div>
);

Імпартуем у компонент useState:

App.jsximport { useState } from 'react';

І завядзём стэйт state:

App.jsxconst [state, setState] = useState(0);

А зараз зробім так, каб па кліку на кнопку наш state павялічваўся бы на 1. Значэнне стэйта будзем выводзіць прама ў тэксце кнопкі:

App.jsx<button onClick={handleStateClick}>
  state click: {state}
</button>

Апішам функцыю для апрацоўкі кліка па кнопцы handleStateClick:

App.jsxfunction handleStateClick() {
  setState(state + 1);
}

Панаціскаем кнопачку і ўбачым, як расце значэнне стэйта.

А зараз давайце створым компонент App, але выкарыстоўваючы не стэйт, а рэф.

Для пачатку, імпартуем у компонент useRef:

App.jsximport { useRef } from 'react';

І завядзём рэф ref. Сваім вынікам хук useRef вяртае аб'ект рэфа з адзінай уласцівасцю current, якое нас і будзе цікавіць у далейшым. Усталюем яго пачатковае значэнне ў 0:

App.jsxconst ref = useRef(0);

Навядзём на кнопачку апрацоўшчык кліка. Памятайце, што мы павінны чытаць/мяняць не сам ref, а яго ўласцівасць current:

App.jsx<button onClick={handleRefClick}>
  ref click: {ref.current}
</button>

Дададзім функцыю для апрацоўкі кліка па нашай кнопцы. Тут мы будзем павялічваць current на 1, як і ў папярэднім прыкладзе са стэйтам. У адрозненне ад стэйта, дзе патрабуецца функцыя setState для змены яго значэння, са ўласцівасцю рэфа мы працуем непасрэдна:

App.jsxfunction handleRefClick() {
  ref.current = ref.current + 1;
}

Цяпер панаціскаем нашую кнопку. І што ж мы бачым? Пры кліку па ёй, як у нас быў першапачаткова 0, так ён і не мяняецца.

Вы, вядома, можаце пачаць сумнявацца ў тым, што значэнне наогул мяняецца. Давайце гэта праверым. Для гэтага ў функцыі апрацоўшчыка кліка дададзім яшчэ радок кода з вывадам значэння current у кансоль:

App.jsxfunction handleRefClick() {
  ref.current = ref.current + 1;
  console.log('ref click: ' + ref.current);
}

А зараз, адкрыўшы кансоль у браўзэры, зноў паклікаем па кнопцы і пераканаемся, што значэнне сапраўды мяняецца пры кожным кліку і ніякага падману няма.

Цяпер мы бачым, што ў адрозненне ад стэйта, змена значэння рэфа не выклікае рэндэрынг компонента. Таму мы кожны раз у тэксце кнопкі бачым пачатковае значэнне 0.

Такім чынам, калі вашыя даныя выкарыстоўваюцца для рэндэрынгу, то захоўвайце іх у стэйце, а калі вам не патрэбны рэндэрынг, у такім выпадку выкарыстанне рэфаў можа стаць больш эфектыўным.

Задание 1

Хай у вашым компоненце ёсць абзац з тэкстам 'text' і кнопка. Зрабіце так, каб кожны раз па кліку на кнопку ў канец тэксту абзаца дадаваўся клічнік. Зрабіце гэта з дапамогай стэйта.

Задание 2

Стварыце компонент App, але замест стэйта цяпер выкарыстоўвайце рэф. Пераканайцеся, што пры націсканні кнопкі тэкст абзаца не будзе мяняцца. Дадайце таксама вывад тэксту абзаца ў кансоль, адкрыйце яе і пераканайцеся, што на самой справе тэкст мяняецца.