«Учебные заметки» Начало работы с ReactHooks

React.js
«Учебные заметки» Начало работы с ReactHooks

📖Предисловие

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

❓ Что такое крючок Зачем нужен крючок?

Рекомендуется заглянуть в блог Дэна Абрамова

image

  1. Логическое повторное использование, если вы используете такие функции, как компоненты более высокого порядка, является более сложным.
  2. Традиционные функциональные компоненты не могут хранить состояние.
  3. Хуки позволяют вызывать функции React в функциональных компонентах.
  4. Использование пользовательских хуков может упростить повторное использование логики.
  5. Хуки — это будущее React
  6. Крючки — это не волшебство. Хуки также спроектированы так, чтобы не зависеть от React.

⛰️useState

useState может добавить хук состояния в функциональный компонент.

Вызов useState возвращает переменную состояния, а также метод для обновления переменной состояния. Параметр useState является начальным значением переменной состояния,Начальное значение действительно только при первом рендеринге..

Метод обновления переменной состояния не объединяет состояние, как это делает this.setState. Вместо этого замените переменную состояния.

Ниже приведен простой пример, который отображает значение count на странице и нажимает кнопку setCount, чтобы обновить значение count.

image

функциональное обновление

Если новое состояние необходимо вычислить из предыдущего состояния. Вы можете передать функцию функции обновления, возвращаемой useState. Аргументом функции является предыдущее состояние.

image

ленивый инициализатор

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

image

пропустить обновление состояния

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

image

подраздел

  1. Обновления useState являются заменами, а не слияниями.
  2. useState может получать параметры функции и использовать возвращаемое значение функции в качестве начального значения.
  3. Функция обновления useState может получать в качестве параметра функцию, а параметром функции является значение состояния предыдущего состояния.
  4. При использовании текущего значения обновления состояния не будут запускать рендеринг.
  5. Несколько useStates могут использоваться для объявления нескольких переменных состояния.

🏁использоватьЭффект

В дополнение к официальной документации рекомендуется прочитатьUm guia completo para useEffect

useEffect позволяет нам выполнять побочные эффекты в функциональных компонентах. Привязка событий, запрос данных, динамическая модификация DOM.

useEffect будет вВыполнить каждую рендеринг RACT. То ли это первое крепление, то ли обновление. (Конечно, мы можем контролировать это поведение)

image

Эффекты, которые необходимо очистить

В традиционных компонентах класса прослушиватели событий обычно добавляются в componentDidMount. Прослушиватель события очищается в componentWillUnmount. Нам нужно разделить нашу логику на разные функции жизненного цикла.

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

То есть в коде ниже. Каждое обновление удаляет предыдущий эффект и выполняет текущий эффект.

image

эффект оптимизации производительности

Каждый раз при выполнении эффекта очистка предыдущего эффекта может привести к ненужной потере производительности. Мы можем управлять выполнением эффекта через второй параметр эффекта. Второй параметр — это зависимость useEffect, useEffect будет обновляться только при изменении зависимости.

image

Когда мы передаем пустой массив в качестве зависимости, он сообщает React, что эффект не зависит ни от какого состояния или свойств. Мы можем использовать это поведение для моделирования componentDidMount или componentWillUnmount.

⚠️ Пожалуйста, помнитеСуществует разница между эффектом и componentDidMount с использованием пустого массива.

image

🤔️В чем разница между useEffect(fn, []) и componentDidMount?

Аналогичный вопрос, почему иногда получается старое состояние или опора в эффекте?

image

useEffect будет захватывать свойства, состояние, но всегда начальное значение.Как показано на рисунке выше, когда мы нажимаем кнопку несколько раз, обратный вызов эффекта через 3 секунды до сих пор печатает начальное значение состояния.

Почему это происходит?

Это из-за механизма закрытия javascript, После вызова функционального компонента состояние внутри функции не очищается механизмом сборки мусора, поскольку оно зависит от обратного вызова внутреннего таймера, а сохраняется в памяти. Поэтому, когда таймер вызывается и выполняется, печатается переменная, хранящаяся в предыдущем закрытии.

Как не получить старый реквизит или состояние?

  1. использовать useRef
  2. Проверьте, отсутствуют ли зависимости, в результате чего эффект не обновляется.

🤔️Как правильно запрашивать данные в useEffect?

Прочитать эту статью — хороший выборHow to fetch data with React Hooks?

Как запросить данные?

image

Как использовать async/await в useEffect?

Асинхронная функция по умолчанию возвращает объект Promise, в то время как в useEffect разрешается только ничего не возвращать или возвращать функцию очистки. В консоли появится следующее предупреждение **Внимание: функция useEffect должна возвращать функцию очистки или ничего. Промисы и useEffect(async() => …) не поддерживаются, но вы можете вызвать асинхронную функцию внутри эффекта.. **

Решение следующее👇

image

подраздел

  1. Для разделения логики можно использовать несколько useEffects. В компонент класса мы обычно добавляем привязку событий, данные запроса и другую несвязанную логику в componentDidMount.
  2. Если вы хотите, чтобы useEffect выполнялся только один раз при загрузке или один раз при выгрузке компонента, вы можете передать пустой массив в useEffect.
  3. useEffect не поддерживает прямое использование асинхронных функций.
  4. Если замыкание сформировано в useEffect, оно получит старые реквизиты или состояние. (Это не имеет отношения к хуку, это связано с характеристиками самого функционального компонента)
  5. Функция, возвращаемая useEffect, функция очистки. Будет вызываться, когда предыдущий эффект очищается.

📰Правила крючка

  1. Используйте Hook только на верхнем уровне, а не для оценки, используйте Hook в операторах цикла.
  2. Используйте хуки только в функциях React

🤔️Почему хук сильно зависит от порядка выполнения?

Анализируем исходный код preact, в preact хук хранится в массиве приватного свойства компонента __hooks._list. От указателя currentIndex зависит как чтение, так и сохранение, при изменении порядка выполнения хуков изменится и текущий индекс, а полученные хуки могут быть выполнены некорректно.

image

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

  1. Пользовательский хук должен начинаться с использования
  2. Пользовательские хуки — это только логическое повторное использование, и состояние в них не будет передано.
  3. Пользовательский может вызывать другой внутренний крюк крюка.
  4. Избегайте преждевременного разделения абстрактной логики

Ниже представлен пользовательский крючок 🌰

💡Пользовательский хук для сбора данных

Когда мы запрашиваем данные двоюродного брата через ajax, используется много общей логики. Например, обработка состояния загрузки, обработка сообщений об ошибках и обработка перелистывания страниц. Мы можем абстрагировать эту логику в публичный хук. Различные API, как параметр кастомного хука.

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

image

как использовать? Выставьте некоторое состояние и setState из пользовательского хука. При изменении страницы данные будут запрашиваться повторно.

image

🚀Другие API

useContext

Получает объект контекста и возвращает значение текущего контекста. useContext может подписываться на изменения контекста. Однако компонентам верхнего уровня по-прежнему необходимо использовать для предоставления контекста компонентам нижнего уровня.

image

useReducer

useReducer получает три параметра: функцию редуктора, начальное значение initialArg, функцию ленивого начального значения init. Функция редьюсера аналогична редюсеру Redux, полученному состоянию и действиям. Вернуть обновленное состояние. Если вы передадите три аргумента, init(initialArg) будет использоваться как начальное значение.

useReducer больше подходит, чем useState, в сложных сценариях.

указать начальное состояние

Второй параметр useReducer может указывать начальное состояние.

ленивая инициализация

Если указан третий параметр useReducer, начальное значение useReducer будет установлено равнымinit(initialArg)

image

пропустить отправку

Если состояние, возвращаемое ReducerHook, совпадает с текущим состоянием, React пропустит рендеринг дочерних компонентов и выполнение эффектов.

🌰 Примеры

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

Ниже приведен пример пользовательского хука, который запрашивает данные из пользовательского хука и преобразует их в метод useReducer.

image

useCallback

useCallback получает в качестве параметров функцию обратного вызова и массив зависимостей. useCallback вернетсяmemoizedфункция.当依赖项改变的时候,会返回的新的memoizedфункция.

image

useMemo

useMemo похож на useCallback. useMemo вернетсяmemoizedстоимость. Пересчитывает при изменении зависимостейmemoizedстоимость.

image

🌟использоватьСсылка

В дополнение к функции получения узлов dom текущее свойство useRef позволяет легко сохранять любое значение переменной. useRef возвращает один и тот же объект ref каждый раз, когда он отображается.

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

image

Если вы хотите после обновления, вы можете очистить таймер, вы можете использовать таймер, чтобы сохранить текущее свойство useRef

image

useLayoutEffect

image
(Красный кружок — синхронная операция)

useLayoutEffect похож на useEffect, но разница в следующем:

  • useEffect, использование useEffect не будет блокировать перерисовку браузера
  • useLayoutEffect, используя useLayoutEffect, заблокирует перерисовку браузера. Если вам нужно вручную изменить Dom, рекомендуется использовать LayoutEffect. Поскольку, если Дом обновлен в useEffect, useEffect не будет блокировать перерисовку, пользователь может увидеть мерцание из-за обновления,

image

🚗Ссылка