Хук аптымізацыі прадукцыйнасці useMemo у React

Першы хук для аптымізацыі прадукцыйнасці, які мы разгледзім - гэта useMemo.

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

Паглядзім, як гэта працуе. Давайце створым кампанент з кнопкай і загалоўкам h3:

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

А зараз зробім так, каб па кліку на загаловак яго колер мяняўся з аранжавага на зялёны і назад. Для пачатку завядзем стэйт isGreen:

App.jsxconst [isGreen, setIsGreen] = useState(false);

Дададзім у атрыбут style загалоўка ўмова змянення колеру загалоўку і навядзім апрацоўшчык кліку:

App.jsx<h3 onClick={() => setIsGreen(!isGreen)}
  style={{ color: isGreen ? 'green' : 'orangered' }}
>Text</h3>

Хай у нас таксама будзе якое-небудзь значэнне, якое будзе павялічвацца па кліку па нашай кнопачцы на адзінку. Завядзем для яго стэйт:

App.jsxconst [num, setNum] = useState(0);

Дададзім апрацоўку кліку па кнопцы:

App.jsx<button onClick={() => setNum(num + 1)}>
  clicks
</button>

Хай таксама ў нас будзе нейкая функцыя square, якая будзе вяртаць квадрат значэння num. Вынік выкліку функцыі мы будзем запісваць у пераменную result:

App.jsxconst result = square(num);

function square(num) {
  return num * num;
}

Вывядзім result у тэксце кнопкі:

App.jsx<button onClick={() => setNum(num + 1)}>
  clicks: {result}
</button>

У выніку ў нас атрымалася наступнае: па кліку на кнопку мяняецца значэнне num, якое затым узводзіцца ў квадрат, а па кліку на загаловак мяняецца колер загалоўка.

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

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

App.jsxfunction square(num) {
  let startTime = performance.now();
  
  while (performance.now() - startTime < 500) {
    // Проста нічога не рабіць ...
  }
  
  return num * num;
}

Панаціскайце зараз на загаловак. Атрымліваецца, што цяпер з-за доўгай працы функцыі square (а кнопку-то мы не кранаем) мы цэлую вечнасць павінны чакаць, каб у загалоўка памяняўся колер!

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

App.jsxconst result = useMemo(() => square(num), [num]);

Зноў панаціскаем на загаловак. Цяпер, калі мы не кранаем кнопку з вылічэннямі і не мяняем такім чынам значэнне стэйта num, то нічога не пералічваецца, і React адлюстроўвае кэшаванае значэнне ў кнопцы, таму наш загаловак хутчэйшанька мяняе свой колер.

Задание 1

Стварыце кампанент App, размясціце ў ім абзац. Завядзіце стэйт text з пачатковым значэннем 'react', хай значэнне стэйта адлюстроўваецца ў якасці тэксту абзаца. Хай па кліку на абзац, яму ў канец тэксту дадаецца клічнік.

Задание 2

Завядзіце яшчэ адзін стэйт num, з пачатковым значэннем 0. Размясціце ў App яшчэ адзін абзац. Зрабіце так, каб пры кліку па ім num павялічвалася на 1.

Задание 3

А цяпер дадайце ў App функцыю triple, якая ў якасці параметра прымае num і вяртае яго патроенае значэнне. Пакладзіце вынік выкліку функцыі у пераменную result. Адлюструйце result у якасці тэксту другога абзаца. Папераклікайце па чарзе на абзацы, адзначце, як павольна дадаюцца клічнікі.

Задание 4

Выпраўце сітуацыю, абгарнуўшы павольную функцыю triple у useMemo.