Любой, кто глубоко погружается в React, испытывает естественное желание понять сложные нюансы его многочисленных крючков. Сегодня мы рассмотрим два ключевых из них: useState и useRef. Эти хуки, хотя и кажутся похожими, имеют разное поведение, которое может существенно повлиять на работу наших приложений React.

Состояние использования

Начнем с useState, любимца публики. Для освежения, вот краткий обзор его основного использования:

import React, { useState } from "react";

function SimpleCounter() {
  const [number, setNumber] = useState(0);
  function increase() {
    setNumber(prevNum => prevNum + 1);
  }
  return (
    <button onClick={increase}>{number}</button>
  );
}

В этом фрагменте useState помогает нам поддерживать состояние внутри наших функциональных компонентов. Каждый раз, когда вызывается setNumber, это приводит к повторному рендерингу, представляя пользователю обновленное состояние.

Не очень реактивный характер useRef

При переходе на useRef он имеет сходство с useState в том, что сохраняет информацию при рендеринге. Но, что важно, обновление значения ref не приводит к повторной визуализации нашего компонента:

import React, { useRef } from "react";

function SimpleLogger() {
  const countRef = useRef(0);
  function logClick() {
    countRef.current += 1;
    console.log(`Button clicked ${countRef.current} times.`);
  }
  return (
    <button onClick={logClick}>Click Me!</button>
  );
}

Обратите внимание на использование .current с useRef. Это позволяет нам получить доступ к его текущему значению. Главный вывод? Использование useRef сохраняет значения постоянными, не запуская ненужную повторную отрисовку.

Практические примеры использования: useRef в действии

Важным вариантом использования useRef является прямой доступ к элементам DOM. React в первую очередь следует принципу декларативного программирования — который определяет, что должна выполнить программа, но не определяет, как это должно быть реализовано — незаметно обрабатывая для нас операции DOM. Однако иногда прямое взаимодействие с элементами DOM становится неизбежным. Вот как:

function TextResizer() {
    const inputRef = useRef();
    function resizeText() {
        const inputElement = inputRef.current;
        inputElement.style.fontSize = "24px";
     }
  return (
    <div>
      <input ref={inputRef} type="text" />
      <button onClick={resizeText}>Enlarge Text</button>
    </div>
  );
}

Прикрепив ref к входным данным, мы можем получить доступ к его свойствам и изменить их, как видно из функции изменения размера.

Объединение концепций

Представьте себе приложение, которое отслеживает цены на акции. Вы можете использовать useState для отображения последней стоимости акций и useRef для вызова предыдущей стоимости. Используя оба варианта, вы можете эффективно отображать сравнение в реальном времени, не вызывая дополнительных рендерингов для предыдущего значения. Эта гармония демонстрирует, как сочетание хуков может повысить производительность и удобство использования вашего приложения.

Заключительные мысли

Напомним, что хотя и useState, и useRef хранят информацию, только первый инициирует повторный рендеринг при обновлениях. Крайне важно различать их различия для разработки эффективных приложений React. Помните, речь идет не о useState и useRef, а о понимании того, когда какой использовать.