Функциональные компоненты и хуки React

React.js

React Component

binlive前端开发,web开发,node,vue,react,webpack
Компонент класса является нашим наиболее распространенным компонентом в настоящее время, он имеет некоторые функции, такие как состояние и жизненный цикл внутри компонента. Компонент класса — это наиболее распространенный способ написания компонентов React, который должен объявить класс и наследовать класс компонента реакции. Компоненты класса широко используются и имеют ряд методов, таких как внутреннее состояние и жизненный цикл.
binlive前端开发,web开发,node,vue,react,webpack
Функциональный компонент написан более лаконично, он получает переданное в родительскомpropsобъект и вернутьReact 元素, что по сути является фундаментальнымФункция JavaScript.

Class Component

React createClass

Существует два способа создания компонента класса.На следующем рисунке показан компонент, определенный React.createClass, который совместим с записью es5.Это также способ создания компонента в начале React.

binlive前端开发,web开发,node,vue,react,webpack

Инструкции по написанию:
  1. propTypesОн используется для обработки проверки типа свойств определения проверки.PropTypes получены из React.От этого метода записи отказались после React 16.0.0, и PropTypes были извлечены отдельно дляprop-typespackage, поэтому в более новой версии сначала нам нужно выполнить проверку типов, и нам нужно вручную ввести модуль prop-types
  2. getInitialStateиспользуется для инициализации состояния,getDefaultPropsИспользуется для определения значения свойства реквизита по умолчанию, использование этих двух функций несколько похоже на методы data и props в Vue now.
  3. Компонент createClass должен определитьrender函数, который вернет узел реакции для рендеринга представления
Класс ES6 реагирует

Это обычная запись компонента реакции класса ES6.

binlive前端开发,web开发,node,vue,react,webpack

Инструкции по написанию:
  1. Реагировать вv0.13.0представилComponent API, с некоторыми инструментами преобразования кода мы можем использовать последний синтаксис es
  2. Компоненты также должны определятьrender函数Используется для рендеринга представлений, поскольку es6 поддерживает сокращение метода, рендеринга и других определенных функций больше не нужно объявлять ключевое слово function.
  3. Состояние инициализируется в конструкторе, здесь видно, что естьsuperCall, ES6 предусматривает, что конструктор подкласса должен один раз выполнить метод super.Если в подклассе не определен метод конструктора, этот конструктор будет добавлен по умолчанию и вызовет super. Если мы объявляем функцию конструктора, мы должны вызвать super в конструкторе. Мы можем получить доступ к этому объекту только после обычного вызова метода super(props).Если мы хотим получить доступ к this.props в конструкторе, нам нужно передать реквизиты в супер, конечно.К нему также можно получить доступ напрямую через реквизит. Но независимо от того, определен конструктор или нет, передается ли super в параметре props, this.props можно использовать в других жизненных циклах реакции, которая автоматически прикрепляется React.
  4. Компоненты, созданные путем наследования Component API, следуют правилам класса es6. React не будет автоматически связывать это для нас. Чтобы получить к этому правильный доступ, нам нужно связать указатель this в конструкторе. Но если методов много, в периодическом конструкторе будет написано много избыточного кода функции привязки.
использовать это элегантное решение

binlive前端开发,web开发,node,vue,react,webpack
здесь, чтобы сказатьсинтаксис поля классаэто предложение Определение синтаксиса поля общедоступного класса:字段名 = 引用值. Перед выполнением метода конструктора содержимое поля было присвоено экземпляру.

binlive前端开发,web开发,node,vue,react,webpack
Так что теперь более популярный способ написания такой Согласно синтаксису поля общедоступного класса, мы можем напрямую передать字段名 = stateсодержимое объекта для объявления объекта состояния. Поскольку стрелочные функции не имеют самих себяthis, где он будет указывать на экземпляр текущего класса. Заимствуя из предложения поля открытого класса, мы можем напрямую объявить функцию стрелки, чтобы исправить указатель this метода. Таким образом, нам не нужно создавать состояние в конструкторе. Также нет необходимости писать много функций, связывающих this в конструкторе. Если нет других операций, мы можем полностью опустить конструктор.

React.PureComponent

binlive前端开发,web开发,node,vue,react,webpack

PureComponentИнтерьер унаследован от React.Component, а в компоненте React.Component мы можем использоватьshouldComponentUpdateЧтобы определить, следует ли повторно отправлять и повторно отображать, React.PureComponent использует его внутриshallowEqualНеглубокое сравнение. Сравнение длин до и после неглубокого сравнивает обновленное состояние, и реквизиты являются согласованными, определяя ли новые данные или уменьшение количества реквизитов или состояния. Тогда это позвонит внутреннемуobjectisМетод поверхностно сравнивает состояние и реквизит до и после, objectis похож на метод Object.is из es6, а Object.is похож на оператор конгруэнтности ===, но он не ведет себя одинаково при сравнении +0 и -0, == = возвращает true, а он false.

binlive前端开发,web开发,node,vue,react,webpack
Из-за неглубокого сравнения, когда параметр в реквизитах является ссылочным типом, при изменении значения в данных объекта компонент PureComponent не будет запускать повторный рендеринг, поскольку они ссылаются на один и тот же адрес памяти.

Functional Component

binlive前端开发,web开发,node,vue,react,webpack
Функциональные компоненты очень просты и чисты, функция — это компонент.

  • Функциональные компоненты не имеют жизненного цикла
  • также не имеет собственного внутреннего состояния
  • Поскольку это просто функция, у нее нет внутреннего this при вызове.

Вышеприведенное изображение является очень простым примером функционального компонента.Хотя функциональный компонент по сути является функцией JavaScript, похоже, что в примере нет никакого API или метода, использующего реакцию, но мы все же вводим реакцию, потому что она возвращается внутри компонента. , Элемент реакции использует jsx, который, по сути,React.createElementСинтаксический сахар babel может скомпилировать для нас jsx после настройки babel, что упрощает процесс написания createElement.

Stateless Component

binlive前端开发,web开发,node,vue,react,webpack
В прошлом функциональные компоненты также назывались компонентами без сохранения состояния. Функциональные компоненты не требуют инстанцирования и не имеют внутри себя никакого управления жизненным циклом или состоянием, они просто принимают реквизиты и отрисовывают их. Использование компонентов без сохранения состояния может быть лучше для оптимизации производительности при работе с простым презентационным контентом, не относящимся к пользовательскому интерфейсу.

Разница между классом и функционалом

binlive前端开发,web开发,node,vue,react,webpack

Функциональные компоненты не должны объявлять классы, что позволяет избежать большого количества кода, такого как расширения или конструкторы, и не нужно решать проблему этого указания. Что более чисто, так это то, что функция является компонентом React официально заявил, что компоненты React всегда были больше похожи на функции, и мы, кажется, ближе к принципам реагирования, когда пишем функциональные компоненты. Ссылочная прозрачность — это концепция функционального программирования, и лично я считаю, что функциональные компоненты следуют концепции чистых функций.

чистая функция

binlive前端开发,web开发,node,vue,react,webpack

Ссылочная прозрачность — это концепция функционального программирования. Это функция редуктора в редукции. в редуксеreducerнеобходимо определить как чистую функцию, которая соответствует нескольким определениям чистых функций:

  1. Один и тот же вход всегда будет иметь один и тот же выход
  2. Не изменяет входное значение функции Редуктор не может изменять состояние, он может только возвращать новое состояние
  3. Независимость от состояния внешней среды
  4. Нет побочных эффектов

React Hook

Часто код или компоненты, которые мы пишем в начале, относительно просты, и мы можем выбрать функциональные компоненты для завершения простого функционального модуля. Однако позже функция может стать более сложной, и некоторым компонентам функции может потребоваться собственное состояние или жизненный цикл. В настоящее время, если вы хотите получить эти функции, вам может понадобиться использовать его с помощьюкомпоненты более высокого порядкаилиrender propsПомогите ему упаковать слой родительских компонентов класса, чтобы он имел статус и жизненный цикл косвенного владения. Но это всего лишь возможность использовать компонент Class вне сборки функции.

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

Vue Hook

binlive前端开发,web开发,node,vue,react,webpack

Vue выпускает содержимое возможного обновления 3.0 На рисунке выше показаны относительно большие изменения в этом обновлении.funtion based api.

Сравнивая написание 2.0 справа,templateЭто синтаксис шаблона из предыдущего. Чем более особеннымsetupфункция. Здесь значением является объект-оболочка, представляющий собой внутреннее состояние компонента, очень похожее на хук usestate в React.onMountedВ соответствии с предыдущей установленной функцией жизненного цикла, окончательный возвращаемый объект метода немного похож на содержимое предыдущего метода данных, связанного с синтаксисом шаблона шаблона, настройка выглядит как простая функция.

binlive前端开发,web开发,node,vue,react,webpack
упоминается автор vuefunction based apiзаимствованныйreact hookподумал о. из-заtypescriptСпособность функций выводить типы лучше, и способ записи объектов, который был более популярен в компонентах vue, теперь, кажется, стал функцией, такой как установка. Что касается более гибкой возможности логического мультиплексирования, мы увидим, как реализовать логическое мультиплексирование позже.

React Hook

binlive前端开发,web开发,node,vue,react,webpack
КрюкReact 16.8новые особенности. Он вводит некоторые новые API на основе функциональных компонентов, позволяя вам писатьclassиспользовать в случаеstateи другие функции React.

Мы видим здесь, чтоuseStateAPI, который может вызываться с параметрами и возвращает массив. В массиве есть два содержимого, первое — это состояние (state), а второе — состояние набора (setState). Используя функцию деструктуризации массива es6, мы можем десемантически назвать его в соответствии с нашими потребностями. Параметр init только в useState. После первой инициализации метода, даже если функциональный компонент будет обновлен, его состояние не будет сброшено, поэтому он всегда может сохранять текущее состояние. Это также позволяет функциональным компонентам иметь внутреннее состояние и жизненный цикл.

Использование крючков и меры предосторожности

обновление состояния пропуска хука

binlive前端开发,web开发,node,vue,react,webpack

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

binlive前端开发,web开发,node,vue,react,webpack
Вызовите функцию обновления setData установленного нами хука и передайте данные ссылочного типа, которые были изменены для запуска обновления.React пропустит рендеринг дочернего компонента и выполнение эффекта. (React использует Object.is для сравнения состояния до и после). Поскольку адрес ссылки не меняется, повторного рендеринга не происходит. Мы можем использовать следующие два метода на рисунке для поверхностного копирования объекта, а затем использовать его для решения этой проблемы.

Введение в использованиеЭффект

binlive前端开发,web开发,node,vue,react,webpack
useEffect Как и его название, он может использовать некоторые побочные эффекты в функциональных компонентах, которые мы можем использовать для имитации некоторых операций жизненного цикла. useEffect принимает два параметра, первый параметр — это функция обратного вызова, которая будет запущена после некоторых обновлений состояния и рендеринга компонента, а второй параметр — это массив, который является необязательным параметром.

Правила использованияEffect следующие:

  1. Когда второй не существует, обратный вызов запускается после первой инициализации и после каждого повторного рендеринга.
  2. Когда массив существует и имеет значения, обратный вызов запускается после каждого рендеринга, если какое-либо значение в массиве изменяется.
  3. Когда это пустой массив, обратный вызов будет запущен только один раз, как и в случае с componentDidMount.
  4. Каждый операционный эффект может вернуться к четкой функции.

Hooks Rules

binlive前端开发,web开发,node,vue,react,webpack
Официальная документация React гласит: не вызывайте хуки в циклах, условных выражениях или вложенных функциях, используйте хуки только на верхнем уровне. Только использование хуков на верхнем уровне не означает, что код хуков должен быть написан вверху компонента, но код хуков нельзя встраивать в какие-то суждения или условия цикла. Конечная цель этих спецификаций — гарантировать, что при создании и последующем обновлении компонента порядок hoos каждый раз будет постоянным.

Почему хуки должны следовать правилам

binlive前端开发,web开发,node,vue,react,webpack
Это объявление типа для Hook в исходном коде реакции.

  • memoizedState: сохраненное значение состояния после завершения выполнения последней очереди обновления.
  • baseState: инициализирует значение initialState, а newState обновляется после каждого вызова установщика, запускающего диспетчеризацию.
  • baseUpdate: обновление, которое в настоящее время необходимо обновить.
  • Очередь: очередь обновлений текущего хука, в ней будет храниться несколько вариантов поведения при обновлении, и каждый раз, когда мы отправляем установщик, он будет помещаться в эту очередь.

binlive前端开发,web开发,node,vue,react,webpack
Звоним три по очередиuseState hook

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

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

binlive前端开发,web开发,node,vue,react,webpack

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

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

binlive前端开发,web开发,node,vue,react,webpack
Hooks API специально разработан для функциональных компонентов, поэтому мы можем использовать хуки только внутри функциональных компонентов или в пользовательских хуках, включая usestate, useeffect, userref и т. д., а также настраиваемые API-интерфейсы хуков. Более того, пользовательские хуки нельзя использовать внутри компонентов класса. Конечно, для обычного функционального компонента, даже если хук используется внутри, мы можем повторно использовать функциональный компонент внутри классового компонента, что не повлияет на него.

Жизненный цикл крючка

binlive前端开发,web开发,node,vue,react,webpack
Конструктор:Раньше мы больше использовали конструктор для инициализации состояния. При использовании хука для создания состояния вы можете передать initialState для инициализации. Если у вас сложная логика вычислений, параметр инициализации также может быть функцией, если возвращаемое расчетное значение может быть

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

binlive前端开发,web开发,node,vue,react,webpack
КомпонентДидОбновление:Когда NOSEFECHECT не проходит во втором параметре, обратный вызов уволен после первой инициализации и после каждого повторного рендеринга. Это немного отличается от компонентаdiDUpdate. Жизненный цикл компонента не будет вызван, когда он инициализируется и смонтирован. Мы можем использовать USEREF-крючок для хранения значения, чтобы определить, вызывается ли функция в первый раз

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

componentWillUnmountКак упоминалось ранее, каждый useEffect может возвращать функцию очистки. С помощью этой функции мы по-прежнему можем установить второй параметр в пустой массив, так что функция очистки будет вызываться до выгрузки компонента, и мы можем очистить в нем некоторые прослушиватели событий. Более удобно то, что мы можем написать didMount и unMount в одном и том же хуке useEffect.

binlive前端开发,web开发,node,vue,react,webpack
компонентWillReceiveProp:Мы хотим имитировать предыдущую функцию жизни componentWillReceiveProps, мы можем установить второй параметр в параметр props, который необходимо соблюдать. Чтобы сравнить изменения реквизитов до и после, вы можете использовать useRef для сохранения старых реквизитов для достижения цели.

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

логическое мультиплексирование

binlive前端开发,web开发,node,vue,react,webpack
Должностные лица как vue, так и react отметили, что хуки могут лучше повторно использовать логику. Их мотивация заключается в том, что некоторый повторяющийся логический код между компонентами нельзя использовать повторно. Давайте посмотрим, как использовать реагирующие хуки для полного повторного использования логического кода.

Пользовательский крючок

binlive前端开发,web开发,node,vue,react,webpack
Это кастомный хук, то есть мы сами создаем хук.

React требует использования пользовательских хуковuseОпределен в начале, хотя пользовательский хук не является компонентом, ему не нужно возвращать узел элемента React Node.Если элемент возвращается, он становится компонентом функции, но даже в этом случае его также можно использовать внутри метода. состояниеusestateи жизненный циклuseeffectи другие крючки. У него есть свое внутреннее состояние и жизненный цикл.

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

Инструкции по применению:

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

Затем вызовите usestate, чтобы создать состояние внутри пользовательского хука, передайте навигатор онлайн, чтобы инициализировать текущее состояние сети, и получите свое собственное состояние внутри пользовательского хука.

Затем в хуке useeffect нам нужно отслеживать изменение состояния сети.Метод мониторинга сети или отключения нужно вызывать только один раз при создании компонента, поэтому, когда мы передаем второй параметр useeffect, мы передаем только пустой массив , поэтому он будет вызываться только один раз на didmount.

Точно так же при уничтожении компонентов нам также необходимо очистить эти слушатели. Просто очистите эти два метода слушателя в функции возврата хука эффекта.

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

Вызов useОнлайн настраиваемый хук

binlive前端开发,web开发,node,vue,react,webpack

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

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

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

Пользовательский хук жизненного цикла

binlive前端开发,web开发,node,vue,react,webpack
Мы также использовали useeffect API хука для моделирования жизненного цикла в компонентах класса раньше, но если есть больше функциональных компонентов, мы можем использовать эти жизненные циклы во многих компонентах, хотя есть только несколько жизненных циклов, реализованных с помощью useeffect. код, но писать его в каждом компоненте явно не в соответствии с принципом логического повторного использования.

Мы можем реализовать собственный хук useDidMount самостоятельно, что очень просто реализовать. Просто вызовите хук useeffect внутри хука, передайте его первый параметр в качестве параметра функции обратного вызова нашего пользовательского хука и установите второй необязательный параметр в пустой массив, чтобы он вызывался только один раз во время didmount.

Пользовательские хуки в сообществе с открытым исходным кодом

binlive前端开发,web开发,node,vue,react,webpack
Это проект use hook с множеством звездочек на github, называемый react-use, который на данный момент имеет 8,7 тыс. звездочек.

Этот проект с открытым исходным кодом помогает нам собрать серию инкапсулированных пользовательских хуков, таких как эти хуки жизненного цикла, которые нам нужно только ввести для реализации этих жизненных циклов. Включая некоторые хуки didMount, unmount, update и прочие.

Компонент индикатора выполнения, написанный с использованием React Hook

binlive前端开发,web开发,node,vue,react,webpack

Поделитесь компонентом индикатора выполнения дуги React Hookreact-arc-progress, это был плагин, написанный на es6 раньше, а затем, чтобы продолжить реакцию, он был преобразован в компонент реакции.

  1. Поскольку используется API реагирующих хуков, его можно использовать только в версии реакции >= версии 16.8.0.
  2. Используемый машинописный текст, если также используется ts, использование компонентов автоматически будет иметь подсказки вывода типа для параметров и методов.
  3. Исходный код использует спецификации tslint и Airbnb для проверки стиля кода строки.

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

  • Большинство круглых индикаторов выполнения представляют собой полные круги.Этот компонент может иметь форму дуги, а его начальное и конечное положение можно свободно определять.
  • Можно передать значение, и оно будет автоматически увеличиваться по мере роста индикатора выполнения.
  • Один или несколько текстовых узлов могут быть переданы в
  • Толщина индикатора выполнения может быть определена таким образом, чтобы внутренний слой превышал внешний слой.
  • Фон индикатора прогресса может быть текстурирован
  • Скорость анимации можно регулировать с помощью порога скорости или фиксированной продолжительности анимации.

Адрес GitHub, пожалуйста, поставьте звезду ◔ ‸◔