Документация: https://reactjs.org/docs/hooks-intro.html

GitHub: https://github.com/JoeG21/medium-ex/blob/master/react-hooks-useState/src/App.js

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

Есть две вещи, которые вам нужно знать, прежде чем включать хуки в свое приложение. Во-первых, вы можете использовать хуки только в функциональных компонентах. Это потому, что уже есть способы установить состояние в компонентах класса, таких как конструктор() и состояние = {}.

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

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

Во-первых, мы должны импортировать useState в наш компонент. После этого мы можем объявить useState, функцию, которая всегда возвращает массив с двумя значениями. Первое значение будет текущим состоянием (цветом), а второе значение — функцией, позволяющей обновить текущее состояние (setColor). Мы можем называть эти 2 значения как угодно, просто рекомендуется называть второе значение «set‹the 1st value›» для удобства чтения. Затем мы присваиваем этому массиву значение useState, и все, что передается в наши параметры, будет нашим состоянием по умолчанию, в данном случае «?».

Чтобы вызвать состояние в нашем возврате, мы просто помещаем 1-е значение нашего массива, которое мы назвали «цвет» (строка 27), в наш JSX. На данный момент у нас должно быть несколько кнопок с надписью «Красный», «Зеленый» и «Синий» с распечатанным знаком вопроса. Теперь, чтобы изменить состояние, когда пользователь нажимает на кнопки, нам просто нужно добавить прослушиватели событий, как это делается в компонентах класса, и добавить логику к этим функциям.

Как я уже упоминал, useState возвращает 2 значения. Здесь в игру вступает второе значение функции обновления (setColor). Мы объявили (строки 8, 12 и 16) их и передали то состояние, в которое мы перешли, для обновления в параметрах. Каждый раз, когда мы вызываем нашу функцию обновления (setColor), она будет повторно отображать наш компонент с новым значением для нашего состояния (цвета), точно так же, как это происходит с любым другим установленным состоянием внутри компонента класса. Когда вы обновляете состояние, ваш компонент перерисовывается!

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

Эта функция принимает аргумент, который мы можем назвать как угодно, чтобы представить значение предыдущего состояния («prevState» — это то, как я назвал его). Используйте выражение функции стрелки, чтобы представить, до чего вы хотите обновить состояние.

Теперь, когда наше приложение работает с хуками, нам нужно больше узнать об useState.

В useState есть 2 способа передачи состояния. Первый — это жестко закодированная версия, как в нашем примере (строка 5). Это будет всегда отображать компонент каждый раз, когда вы запускаете функцию. Таким образом, это может снизить производительность приложения, если это что-то сложное, например Фибоначчи.

Другой способ — функциональная версия. Использование функциональной версии useStateзапустит функцию только один раз, когда компонент отрисовывается. Это отлично подходит для сложных вычислений. Мы можем доказать это, поместив console.log в наш код и проверив страницу, чтобы посмотреть на нашу консоль.

Наконец, useState работает иначе при работе с объектами.

Я добавляю новое состояние с именем «phrase» со значением состояния по умолчанию «Hello World» (строка 5) и вызываю значения, которые мы объявили в строках 6 и 7, в наш JSX в строках 36 и 38.

Как видите, всякий раз, когда мы меняем цвета, наш «Hello World» полностью исчезает. Он не объединяет наше старое состояние, в отличие от того, что атомарно сделал бы компонент класса. Все в состоянии переопределяется независимо от того, что мы обновляем, из-за того, что мы передаем в функцию обновления (setState в строке 12, 18 и 24).

Теперь, если вы хотите использовать объект, мы просто используем оператор распространения (…) для сохранения предыдущего состояния.

В строках 12, 18 и 24 «…prevState» — это значения внутри нашего useState (цвет: «?», фраза: «Hello World»), тогда мы просто обновляем наш цвет.

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

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

Как правило, вы должны следить за глубоко вложенными объектами в состоянии React. Это может привести к неожиданному поведению, поэтому лучше избегать использования объектов при установке состояния с помощью хуков.

Вот и все, теперь вы можете использовать useState в своих приложениях! Хотелось бы, чтобы я научился этому намного раньше, потому что это делает состояние в 10 раз проще и читабельнее.

Ради интереса я написал первый пример в компоненте класса, который имеет 863 символа, сравните с функциональным компонентом, который имеет 767!

Спасибо за прочтение и буду рада обратной связи! Вы, конечно, можете проверить мой GitHub для кода и официальной документации!

Документация: https://reactjs.org/docs/hooks-intro.html

GitHub: https://github.com/JoeG21/medium-ex/blob/master/react-hooks-useState/src/App.js