Краткий обзор React Hooks


Что такое хуки в React?

Хуки  это функция, добавленная в React v16.8, при помощи которой можно зацепиться за состояние и метод жизненного цикла React из функционального компонента. Хуки позволяют использовать все возможности React без написания классовых компонентов и решают множество, казалось бы, несвязанных между собой, проблем в React. Среди этих проблем можно выделить следующие: 

  • сложность повторного использования логики состояний между компонентами;
  • громоздкие компоненты затрудняют понимание кода;
  • классы усложняют разработку.

Какие же преимущества дает использование хуков?

  • Применение хуков дает возможность извлечь логику состояния, а значит и использовать логику состояния, не затрагивая дерево компонентов;
  • Один компонент при помощи хуков можно разбить на маленькие функции по их назначению, а не на основе методов жизненного цикла;
  • Хуки позволяют использовать больше возможностей React без написания классов.

Хуки можно назвать своеобразным способом избежать изучения сложных функциональных или реактивных подходов. 

Для лучшего понимания преимуществ этого способа следует рассмотреть подробнее основные хуки и привести несколько примеров.

useState 

Начнем с useState  функция, которая вызывается чтобы наделить наш функциональный компонент внутренним состоянием. По своей сути она близка к this.setState в классах. Первым и единственным аргументом useState принимает начальное состояние. Возвращаемым значением useState будет пара значений: текущее состояние и функция, обновляющая его. 

Пример:

// Объявление новой переменной состояния «count»
const [count, setCount] = useState(0);

Здесь происходит объявление переменой состояния и установка ее начального значения, для смены которого можно вызвать setCount.

useEffect 

Следующая функция применяется для того, чтобы задать выполнение дополнительного кода после обновления DOM: с помощью хука эффекта useEffect возможно выполнять побочные эффекты из функционального компонента. В React-классах его аналогами являются сразу несколько функций: componentDidMount, componentDidUpdate и componentWillUnmount.

Пример:

useEffect(() => {
// Обновляем заголовок документа, используя API браузера
document.title = `Вы нажали ${count} раз`;
});

После каждого рендера, после того, как React внесёт все изменения в DOM, данная функция-эффект будет вызвана.

useContext

Следующим основным хуком является useContext.

Контекст в React  это способ для компонента-потомка получить доступ к значению в родительском компоненте. Данная необходимость возникает довольно часто. И обычно она решается передачей props через компоненты, что не всегда удобно.

Данный хук позволяет делиться значениями через дерево компонентов, с любым компонентом, запрашивающим эти значения.

Простой пример:

const DoctorContext = React.createContext();

function Display() {
const value = useContext(DoctorContext);
return <div>Trust me. I'm the {value}.</div>;
}

function App() {
return (
<DoctorContext.Provider value={"Doctor"}>
<Display />
</DoctorContext.Provider>
);
}

В данном примере контекст создается с использованием функции React.createContext()Context.Provider задействован в App компоненте, в нем устанавливается значение. Теперь любой компонент, которому нужно получить доступ к контексту сможет считать это значение.

И для того чтобы прочитать это значение в функции Display() вызывается useContext с аргументом DoctorContext. Когда значение провайдера будет обновляться, этот хук автоматически сработает с последним значением контекста.

useRef

Довольно часто применяется хук useRef, который возвращает изменяемый ref-объект, свойство которого инициализируется переданным аргументом. Возвращённый объект будет сохраняться в течение всего времени жизни компонента. Распространено применение этого хука как способа получить доступ к DOM, что продемонстрировано на примере ниже:

function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` указывает на смонтированный элемент `input`
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>
            Установить фокус на поле ввода
      </button>
</>
);
}

Этот хук удобен для сохранения любого изменяемого значения. Здесь можно провести аналогию с использованием поля экземпляра в классах.

Так же существуют дополнительные хуки, которые являются вариантами базовых, но их применение обычно необходимо только для конкретных крайних случаев. Нельзя не сказать про интересную возможность создания пользовательских хуков, которые позволяют повторно использовать одинаковую логику состояния в нескольких компонентах без задействования компонентов высшего порядка и рендер-пропсов. Благодаря этой возможности, на данный момент существует множество библиотек хуков, упрощающих задачи разработки.

Правила хуков

Напоследок, следует отметить, пару правил применения хуков.
  • Использовать хуки следует только на верхнем уровне.
Хуки нужно использовать только внутри React-функций, до возврата какого-либо значения из них. Это правило дает гарантию, что хуки будут вызываться в одинаковой последовательности при каждом рендере компонента. И в таком случае, React будет правильно сохранять их состояние между множественными вызовами useState и useEffect.
  • Вызывать хуки следует только из React-функций
Возбраняется вызывать хуки из обычных функций JavaScript. Логика состояния компонента должна быть чётко видна из исходного кода.