Недавно у меня появилась возможность начать использовать хуки React! Я мало что знал о них до того, как погрузился в них, и подумал про себя: «Ну, уроки, кажется, работают отлично, так что в этом такого?»

Перенесемся вперед, и я абсолютно продан! Итак, приступим!

Теперь, когда мы используем классы, мы привыкли видеть что-то вроде этого ...

У нас есть обычный класс, конструктор и объект состояния. Теперь, если мы воспользуемся React Hooks, у нас будет ...

И точно так же у нас заметно меньше кода, который выполняет то же самое за нас!

Это подводит нас к нашему первому вопросу: что такое компонент React и что мы пытаемся моделировать?

Компонент React - это именно то, что ... компонент, который содержит состояние и действует для нас как сосуд для рендеринга JSX.

Раньше мы бы сказали: «О, компонент React похож на класс, но немного меньше…» или «Он похож на функцию, но может возвращать JSX и не может содержать состояние». Мы никогда не используем ключевое слово new для создания экземпляра класса, а использование классов требует понимания «this», а также методов привязки внутри класса. Кроме того, с классами у нас есть методы жизненного цикла, в которых мы смешиваем различные несвязанные части логики. Один метод жизненного цикла componentDidMount может содержать как вызов API, так и в том же методе также может настраивать прослушиватель событий.

Это может привести к тому, что вместе останутся запутанные большие куски несвязанного кода!

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

Итак, без лишних слов, давайте посмотрим!

Вернемся к первой части нашей новой функции CreateTodo.

Сразу же мы видим, что у нас есть возможность разрушить наш реквизит с самого начала! С классами мы не можем увидеть, откуда берутся наши реквизиты, кроме как с помощью this.props! С помощью функциональных компонентов мы можем деструктурировать их прямо из объекта props без необходимости делать это в методе рендеринга!

Во-вторых, мы видим, что у нас есть:

const [todoTitle, setTodoTitle] = useState("");

Этот первый перехватчик называется перехватчиком useState! Хук useState позволяет нам деструктурировать два его свойства. Первый «todoTitle» - это кусок состояния, который мы хотим установить. Это было бы похоже на:

this.state = {
    todoTitle: ""
}

Настройка нашего объекта состояния с помощью свойства todoTitle!

Второе свойство, которое мы можем разрушить, - это функция SETTER! С классами React это выглядело бы так:

this.setState({ todoTitle: "new value here" })

С нашей новой функцией установки это будет выглядеть так.

setTodoTitle("new value here");

Я считаю, что это намного более интуитивно понятно. Мы вызываем функцию, передаем аргумент и вуаля! Мы обновили наше состояние.

Давайте посмотрим немного глубже, чтобы увидеть, как работает ловушка useState!

Если вы знакомы с управляемыми входами, все вышесказанное должно иметь смысл! Для нашего ввода мы можем установить значение = {todoTitle} (гораздо менее подробное, чем this.state.todoTitle!), И мы установим обработчик onChange, который устанавливает наше состояние todoTitle в соответствии с типами, используемыми во вводе.

Теперь, если мы введем строку «Hello there», что вы ожидаете увидеть в консоли? Давайте посмотрим…

Получаем… «Hello Ther…» Мы пропустили последнюю букву! Так почему это?

Когда вызывается наш onTitleChange, он выглядит так…

const onTitleChange = e => {
setTodoTitle(e.target.value);
console.log(todoTitle);
};

Хитрость в том, что setTodoTitle АСИНХРОННЫЙ! Когда он вызывается, он фактически отправляет эту информацию внутреннему движку React. Когда движок получает эту информацию, он может повторно визуализировать компонент! Тем временем, однако, парсер Javascript все еще читает console.log (todoTitle), который в то время НЕ содержит обновленного состояния!

Так, например, если бы пользователь ввел H во входные данные…

setTodoTitle("H") -> Sends off the information to the engine.
console.log(todoTitle) -> todoTitle still = ""

Итак, когда мы получим наш новый todoTitle? Как обновляется состояние в компоненте?

Он устанавливается здесь:

const [todoTitle, setTodoTitle] = useState("")
In this case, this is where todoTitle now = "H"

Когда компонент повторно отрисовывает наше значение состояния todoTitle, деструктурируется из нашего хука useState! Как следует из названия, перехватчик useState перехватывает внутреннее состояние Reacts и позволяет нам получать доступ к его значениям внутри наших функциональных компонентов!

Теперь, если бы мы набрали E во вход

setTodoTitle("HE") -> Sends off the information to the engine.
console.log(todoTitle) -> todoTitle is now "H"

И цикл повторяется!

Теперь, если мы хотим обрабатывать такие вещи, как побочные эффекты, вместо использования методов жизненного цикла мы можем использовать ловушку useEffect!

Обычный хук useEffect выглядит так

useEffect(() => {
  return () => {
  }
},[])

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

Без лишних слов, давайте посмотрим, что это значит!

Написание эффекта для монтажа компонента может выглядеть так!

Хук useEffect здесь действует как componentDidMount. Когда зависимость массива в конце пуста, она сообщает useEffect запускаться только один раз при монтировании компонента! В этом конкретном примере мы выполняем вызов API для сообщений, которые хотим отображать в нашем приложении!

Чтобы предотвратить утечку асинхронной памяти, мы использовали стратегию установки смонтированной переменной, которая затем сообщает setTodos запускаться только тогда, когда компонент «смонтирован».

Чтобы предотвратить запуск setTodos в случае размонтирования компонента, мы вернули функцию, содержащую нашу логику очистки. В этом случае мы просто установили mount = false.

В рамках одного хука useEffect мы позаботились о логике, которая в противном случае должна была бы перейти в componentDidMount и componentWillUmount! И мы сгруппировали эти части связанной логики вместе в одной функции!

Давайте посмотрим, как работает зависимость массива, на примере из нашей формы!

Помните, как мы пропустили последнюю букву, когда пытались написать «Привет!»? Если бы мы хотели увидеть слово целиком, мы бы сделали это! Помещая todoTitle в качестве зависимости нашего массива, мы говорим, что этот эффект срабатывает каждый раз, когда значение todoTitle изменяется. Это что-то вроде componentDidUpdate, но мы можем указать, по каким критериям мы хотим, чтобы он обновлялся! Довольно здорово!

Итак, если мы введем «Hello There» в свой ввод, мы увидим…

Именно то, что мы хотим видеть!

Вы можете иметь столько хуков useEffect, сколько захотите! Это позволяет нам разделять нашу логику.

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

Это лишь пара из готовых хуков, которые предоставляет React. Мы видим, что хуки - прекрасный инструмент, который поможет нам изменить способ написания React!

Надеюсь, вам понравилась эта статья, и вы можете подписаться на меня в твиттере по адресу https://twitter.com/JonWongCodes