React Hooks - это просто функции, и они проще, чем вы думаете

React Hooks - это новое дополнение в React 16.8. Это обновление предоставляет разработчикам возможность использовать состояние и другие функции React с функциональным компонентом. Встроенные хуки, такие как useState, useEffect и т. Д., Широко используются в различных приложениях React. Это гигантский скачок к функциональному программированию.

Когда появились хуки, это показалось немного пугающим. Сам документ состоит из восьми глав, и этот Awesome React Hooks Github предоставляет огромное количество информации по этой теме. Вы уже успели его прочитать?

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

Индивидуальный крючок в одну линию

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

Вот наш первый кастомный хук:

const useMyName = initialName => `My name is ${initialName}.`;

Да, это однострочный код.

Этот настраиваемый хук возвращает строку. Он вызывается в следующем примере:

Этот код выводит сообщение: "My name is Larry."

Пользовательский крючок, возвращающий объект с помощью метода

Пользовательский крючок - это особая функция. Он может вызывать другие хуки, обычно useState и useEffect, вместе с другими встроенными хуками и пользовательскими хуками. Все хуки подчиняются некоторым ограничениям:

  1. Имя хука должно начинаться с «использовать».
  2. Хук должен вызываться из функционального компонента или из другого хука.
  3. Вызывайте хуки только на верхнем уровне. Не вызывайте ловушки внутри циклов, условий или вложенных функций.

Мы пишем более интересный Hook, который возвращает объект. Он по-прежнему принимает начальное имя, как и раньше, но возвращает метод для установки нового имени вместе с сообщением.

Почему-то этот фрагмент кода не работает. Сообщение не отображается на экране, а строка 13 выводит "My name is Larry." на консоли разработчика на неопределенный срок.

Что случилось?

На странице React Справочник по API хуков четко указано:

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

В данном случае myHook.setName(‘Larry’) - это мутация. Помещение его в основной текст App приводит к тому, что изменение не отражается в пользовательском интерфейсе. Кроме того, setName - это изменение состояния, и оно запускает цикл повторного рендеринга для повторного вызова setName. Ситуация повторяется, и эта цепная реакция тянется в бесконечный цикл.

Нам нужно поместить setName в useEffect. Затем изменение состояния отражается в пользовательском интерфейсе.

Мы передаем пустой массив ([]) в качестве второго аргумента для однократного запуска эффекта. Интересно, что без этого мы снова можем увидеть бесконечный цикл console.log. По умолчанию useEffect запускается как после первого рендеринга, так и после каждого обновления. setName - это изменение состояния, которое вызывает повторный рендеринг. Затем снова вызывается useEffect. Это приводит к бесконечным повторным рендерам.

Есть еще один интересный факт о useEffect. Строка 15 выводит: “My name is undefined.” Почему это undefined вместо Larry? Это потому, что setName может произойти не сразу.

Вместо передачи пустого массива мы можем передать необязательный второй аргумент ([myHook.message]) в Строку 16. Затем React пропускает применение эффекта, если myHook.message не изменяется между повторными рендерингами. При таком подходе мы видим два консольных сообщения:

"My name is undefined."
"My name is Larry."

Вот объяснение: setName не происходит сразу. Он распечатывает "My name is undefined." Это изменение состояния вызывает повторный рендеринг, который вызывает второй вывод, "My name is Larry." После этого myHook.message не изменяется. Следовательно, useEffect больше не будет выполняться.

Слишком много ошибок при написании или использовании хуков? Чтобы избежать подобных ошибок, рекомендуется установить специальный плагин ESLint для хуков: npm install eslint-plugin-react-hooks --save-dev.

Этот плагин ESLint необходимо настроить следующим образом:

По умолчанию Create React App включает eslint-plugin-react-hooks.

Если вы используете VSCode, расширение ESLint может показывать вам ошибки или предупреждения при редактировании кода.

Пользовательский крючок, возвращающий объект с помощью пользовательского интерфейса

Наш предыдущий более привлекательный Hook возвращает объект из двух элементов:

{
  setName: newName => setCurrentName(newName),
  message: `My name is ${currentName}.`
}

Мы хотим сделать его немного интереснее, добавив еще один элемент, чтобы иметь пользовательский интерфейс выбора имени переключателя, который выглядит следующим образом:

Вот фрагмент кода:

Этот Hook возвращает объект из трех элементов:

Значение display - JSX, расширение синтаксиса JavaScript. Вообще говоря, пользовательские хуки могут возвращать значения, объекты, методы, JSX и многое другое.

Пользовательский хук, возвращающий массив

Пользовательский хук может возвращать что угодно, если вызывающий знает, как это обработать.

Мы переписываем предыдущий более привлекательный Hook, чтобы он был немного более привлекательным. Он возвращает массив аналогично тому, как это делает useState. Вызывающий объект разрушает массив для метода, сообщения и пользовательского интерфейса. Поскольку метод не используется, его не нужно указывать в строке 21.

Коллекция хуков React

Крючки получили широкое распространение. Новые пользовательские хуки появляются каждый день.

Это сборник React Hooks:

Крючки открывают новый мир возможностей. Вы готовы создать собственный крючок?

Спасибо за прочтение. Я надеюсь, что это было полезно. Вы можете увидеть другие мои публикации в Medium здесь.