Главная страница
Навигация по странице:

  • Переход от классов к хукам

  • Хук useState

  • destructuring

  • spread-оператора

  • Управление функциональными компонентами Введение в хуки


    Скачать 0.6 Mb.
    НазваниеУправление функциональными компонентами Введение в хуки
    Дата31.10.2022
    Размер0.6 Mb.
    Формат файлаdocx
    Имя файла123.docx
    ТипГлава
    #763166

    Глава 4 Управление функциональными компонентами

    Введение в хуки

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

    Мы можем создавать свои хуки, однако React по умолчанию уже предоставляет ряд встроенных хуков:

    • useState: предназначен для управления состоянием компонентов

    • useEffect: предназначен для перехвата различного рода изменений в компонентах, которые нельзя обработать внутри компонентов

    • useContext: позволяет подписываться на контекст React

    • useReducer: позволяет управлять локальным состоянием сложных компонентов

    • useCallback: позволяет управлять функциями обратного вызова

    • useMemo: предназначен для управления мемоизированными (грубо говоря кэшированными) значениями

    • useRef: возвращать некоторое изменяемое значение, например, ссылку на html-элементы DOM, которыми затем можно управлять в коде JavaScript

    • useImperativeHandle: настраивает объект, который передается родительскому компоненту при использовании ref

    • useLayoutEffect: аналогичен хуку useEffect(), но вызывается синхронно после всех изменений в структуре DOM

    • useDebugValue: предназначен для отображения некоторого значения в целях отладки

    • useId: предназначен для генерации уникального идентификатора

    • useTransition: применяется для создания переходов при рендеринге

    • useDeferredValue: позволяет отложить рендеринг некритичных частей структуры DOM

    • useSyncExternalStore: предназначен для синхронизации данных с внешними хранилищами

    • useInsertionEffect: предназначен для библиотек, которые используют CSS в JS, для оптимизации при внедрении стилей при рендеринге

    Переход от классов к хукам

    Рассмотрим простейший пример, как мы можем перейти от классов к хукам. Допустим, у нас есть следующий класс-компонент:







    Здесь определен компонент ClickButton, который принимает через props некоторое значение increment. В конструкторе определяется состояние в виде переменной counter, которая равна 0. Кроме того, в классе определяется метод press(), в котором изменяется состояние компонента.

    Для изменения состояния вызывается другой метод - incrementCounter, который берет из props значение increment и использует его для увеличения значения переменной counter.

    В коде класса-компонента определяется кнопка, по нажатию на которую как раз и вызывается метод press():






    В итоге по нажатию на кнопку мы получим увеличение переменной counter:



    Теперь определим аналогичный компонент с использованием хуков:





    В данном случае определен функциональный компонент ClickButtonHook, так как мы не можем использовать хуки в классах-компонентах, а только в функциях.

    Вначале определяем переменные состояния:



    В данном случае определяются две переменных: count и setCount. Переменная count хранит состояние компонента, а переменная setCount позволяет изменять значение переменной count.

    В функцию useState() передается число 0 - это то значение, которое по умолчанию получает переменная count.

    Для изменения состояния в компоненте определена функция press(), которая выполняет выражение setCount(count + props.increment); - к переменной count прибавляется значение increment из props. Это выражение (count + props.increment) и определяет новое значение переменной count. Таким образом, состояние компонента ClickButtonHook будет изменено.

    В коде также определена кнопка, по нажатию на которую вызывается метод press(). В итоге мы получим ту же программу, но с использованием хуков. И как видно, этот код несколько короче, чем код класса-компонента.

    Подключение хуков


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


    Ограничения при использовании хуков


    Хуки имеют ряд ограничений при определении и использовании:

    • Хуки вызываются только на верхнем уровне (top-level) компонента. Они НЕ вызываются внутри циклов, условных конструкций, внутри стандартных функций javascript.

    • Хуки можно вызывать только из функциональных компонентов React, либо из других хуков. Но их нельзя вызывать из классов-компонентов.

    Функциональные компоненты можно определять как обычные функции:


    Хук useState


    Одним из наиболее используемых встроенных хуков является useState, который позволяет определить состояние компонента. Например, определим простейший компонент, который применяет этот хук:





    Итак, здесь определен компонент Counter, причем определен в виде функции, так как мы не можем использовать хуки в классах-компонентах.

    Вначале определяем переменные состояния:



    В данном случае определяются две переменных: count и setCount. Переменная count собственно хранит состояние - некоторый объект, а переменная setCount представляет функцию, которая позволяет изменять значение переменной count.

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

    Что за значение будет хранить переменная count? А хранит она то значение, которое передается в функцию useState() - в данном случае это число 0.

    Чтобы инспектировать значение переменной count, ее значение выводится в заголовке h3:



    В коде компонента определена кнопка, которая по нажатию будет вызывать изменение значения переменной count



    В данном случае применяется стрелочная функция, которая выполняет выражение setCount(count + 1), которое увеличивает значение count на единицу.

    В итоге по нажатию на кнопку изменится значение переменной count:


    Определение переменных состояния


    Итак, хук useState определяет переменные состояния. Единственный аргумент хука определяет начальное значение переменной состояния. А возвращает useState() массив из двух объектов. Первый объект представляет значение состояния, а второй объект представляет функцию, которая обновляет это значение. Например, выше состояние определялось следующим образом:



    В данном случае для определения переменных применяется синтаксис декомпозиции или destructuring. Но также мы могли бы использовать и стандартный синтаксис массивов для получения значений переменных:


    Определение нескольких переменных состояния


    При необходимости можно определять множество переменных состояния. Например:





    В данном случае определены две переменных состояния: name и age.



    Также мы можем изменять значения этих переменных. Например, добавим к предыдущему примеру изменение переменных:







    В данном случае для обновления значений переменных name и age в компоненте определены два поля ввода. Событие onChange каждого поля привязано к одной из функций компонента - handleAgeChange или handleNameChange. Поэтому изменение значения в каждом поле вызовет соответствующую функцию. Например, при вводе текста для имени пользователя будет вызываться функция handleNameChange():



    По умолчанию в функцию обработки события поля ввода input передается информация о событии, из которой с помощью свойства target.value мы можем получить введенное значение и затем передать его в функцию изменения состояния: setName(event.target.value)



    Однако нам необязательно определять отдельные переменные для хранения состояния. Хук useState равным образом позволяет определять массивы и комплексные объекты. Например, перепишем предыдущий пример, объединив переменные в один объект:







    Здесь состояние компонента представлено сложным объектом, который имеет два свойства: name и age. Но в данном случае при обновлении следует учитывать, что функция обновления (в данном случае - setUser) полностью изменяет хранимое значение состояния, поэтому нам надо полностью переопределить его свойства:



    В итоге мы получим тот же результат:



    Однако если у нас объект имеет множество свойств, то перечисление всех свойств и их значений может быть утомительным. И в этом случае мы можем сократить запись с помощью spread-оператора ...:







    написать администратору сайта