Хук useRef за рад са рефовима у React-у

На овој лекцији ћемо радити са рефовима. За једноставност, хајде да размотримо рад хука useRef у поређењу са хукoм 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, али уместо стања сада користите реф. Уверите се да при притиску дугмета текст пасуса неће се мењати. Додајте такође испис текста пасуса у конзолу, отворите је и уверите се, да се текст у ствари мења.