React - одна из самых популярных библиотек для создания пользовательских интерфейсов на рынке сегодня, и ее инженеры стремятся поддерживать этот статус за счет внедрения совершенно новой системы для написания функциональных компонентов (ранее не сохраняющих состояние) в React 16.8.0. Чтобы решить множество проблем, связанных с передачей информации в приложении React, были введены хуки, позволяющие разработчикам использовать состояние и другие функции компонентов без написания класса.

Команда React стремится оставаться актуальной и обеспечивать лучший пользовательский интерфейс как для разработчика, так и для пользователя. Софи Альперт, менеджер основной команды React в Facebook, говорит, что они очень осторожны и внимательны, когда решают добавить новый API в свою библиотеку. Цель всегда состоит в том, чтобы программисту было проще компилировать код, а пользователю, в свою очередь, было меньше кода для загрузки. С появлением хуков у нас появился более прямой API для мощного комбинирования уже известных нам концепций: свойств, состояния, контекста, ссылок и жизненного цикла.

За пять лет с момента своего создания React разработал множество, казалось бы, не связанных между собой проблем. Например, он не предоставляет способ «прикрепить» повторно используемое поведение к компоненту, несмотря на компоненты и инструменты более высокого порядка, такие как свойства рендеринга. И эти шаблоны требуют от программиста реструктуризации компонентов, и запутывают код так, чтобы он был абстрагирован до неузнаваемости в «аду оберток». Благодаря хукам React сформировал лучший примитив для совместного использования логики с отслеживанием состояния. Теперь его можно протестировать независимо и повторно использовать без изменения иерархии компонентов.

Более того, сложные компоненты постоянно превращаются в неуправляемую неразбериху логики с отслеживанием состояния, пронизанную побочными эффектами и язвами для глаз. Методы жизненного цикла часто объединяют несвязанную логику в одну функцию, что приводит к ошибкам и несоответствиям. Как правило, невозможно разделить эти коллекции кода на отдельные методы из-за беспорядочного размещения состояния в сложном приложении React. Это заставляет многих разработчиков использовать дополнительную библиотеку управления состоянием (такую ​​как Redux), но это увеличивает уровень абстракции, требует от вас переключаться между разными файлами и затрудняет повторное использование компонентов.

Чтобы привести в порядок этот беспорядок кода с отслеживанием состояния, хуки позволяют разделить один компонент на более мелкие функции в зависимости от того, какие части связаны между собой, вместо использования методов класса и жизненного цикла. Разработчики и компьютеры часто испытывали трудности с пониманием структуры классов в React, поскольку this в JavaScript ведет себя совершенно иначе, чем в большинстве языков, что требует использования «привязки».

Хорошо, достаточно предыстории, давайте перейдем к основам использования хуков с введением 'useState'. Ниже приведен пример из React docs хука для простого счетчика, а также то, как счетчик обычно разобрались в классе.

Пример крючка:

import React, { useState } from 'react';

Example = (props) => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Пример эквивалентного класса

class Example extends React.Component {
  state = {
    count: 0
  }
  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

Как видите, useState Hook позволил нам сохранить использование функционального компонента при включении состояния. Как это работает? А что такое на самом деле крючок?

Ну, хуки - это особая функция, которая позволяет вам «подключиться» к функциям React. Раньше вам нужно было преобразовать любой компонент в класс перед добавлением состояния, но с указанным выше useState мы смогли добавить эту логику непосредственно к нашим функциональным компонентам. Фактически, хуки не работают в компонентах класса, вместо этого они заменяют необходимость их использования.

Вы спросите, как на самом деле работает useState?

useState ===this.state

Вызов useState объявляет «переменную состояния». Как и любая переменная, это способ «сохранить» некоторые значения между вызовами функций. Обычно переменные «исчезают» при выходе из функции, но переменные состояния сохраняются React. Начальное состояние, которое мы хотим установить, передается в качестве аргумента useState(), и если мы хотим сохранить несколько значений в состоянии, мы просто вызываем useState() еще раз и определяем новое начальное значение.

useState() возвращает пару значений: текущее состояние и функцию установки, которая его обновляет. Следовательно, мы написали const [count, setCount] = useState(0) в приведенном выше фрагменте . () => setCount(count + 1) в этом примере эквивалентно вызову this.setState({count: this.state.count + 1}) в классе.

Небольшая заметка из React docs:

Вы можете спросить: почему useState вместо этого не называется createState?

Создать не совсем точно, потому что состояние создается только при первой визуализации нашего компонента. Во время следующих рендеров useState дает нам текущее состояние. Иначе это вообще не было бы государством! Также есть причина, по которой имена хуков всегда начинаются с use. Узнайте, почему, в Правилах ловушек.

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

Удачного кодирования!