Как стать профессионалом с помощью React setState() за 10 минут

kak stat professionalom s pomoshhyu react setstate za 10 minut?v=1656524306

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

Просто читайте и получайте удовольствие!

Бери чашку кофе и продолжай читать! ?

Основные понятия setState()

Компоненты React позволяют разделить пользовательский интерфейс (UI) на независимые части, которые можно использовать повторно, чтобы вы могли думать о каждой части в отдельности.

Концептуально компоненты похожи на функции JavaScript. Они принимают произвольные вводы (так называемые реквизиты) и возвращают элементы React, описывающие то, что должно появиться на экране.

Если вам нужно дать пользователю возможность что-нибудь ввести или каким-то образом изменить переменные, которые компонент получает как реквизит, вам понадобится setState.

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

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

Конечно, интерфейс программы динамичен и изменяется со временем. Вот поэтому state было создано.

State позволяет компонентам React изменять свой выход со временем в ответ на действия пользователя, ответы сети и все остальное, не нарушая это правило.

Компоненты, определенные классами, имеют некоторые дополнительные возможности. Локальное состояние является функцией, доступной только классу Components.

setState – это метод API, предоставляемый в библиотеке, чтобы пользователь мог определить состояние и манипулировать им со временем.

Три правила большого пальца при использовании setState()

Не меняйте состояние напрямую

fDk0J1KHkNJKyjha9jV2Ic5VtMHtx0hX54-5
неправильные и правильные способы установки состояния

Обновления состояния могут быть асинхронными

React может создавать несколько пакетов setState() вызывает в единое обновление для производительности.

Поскольку this.props и this.state могут обновляться асинхронно, не следует полагаться на их значения для вычисления следующего состояния.

U802XeMCbWXgWEqgFS1oISKMBIalMacJHIr9
манипулировать состоянием с помощью функционального подхода

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

Обновления состояния объединены

Когда ты звонишь setState()React объединяет предоставленный вами объект с текущим state.

В следующем примере мы обновляем переменную dogNeedsVaccination независимо от другого state переменные.

Слияние неглубоко, следовательно this.setState({ dogNeedsVaccination: true }) оставляет другие переменные неприкосновенными, заменяя только значение dogNeedsVaccination.

MkFjwenYGJsPRkbOZJOcSSHaU26jJ83Y430C

Уважайте поток данных и не указывайте макс.

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

Вот поэтому state часто называют местным или инкапсулированным. Он не доступен ни для одного компонента, кроме того, который владеет и устанавливает его.

Когда ты setState prop и используйте его в своем компоненте, вы нарушаете поток реквизитов визуализации. Если по какой-либо причине параметр, переданный в ваш компонент, изменился в родительском компоненте, ребенок не будет повторно воспроизводиться автоматически?!

Давайте проверим пример:

BdJA87j3HTnLGzQMnx0enaMdNXelqTzrkgZ1

Вот у вас есть Home Компонент, генерирующий магическое число каждые 1000 мс и устанавливающий его собственным state.

После этого он отображает число и вызывает три Child Компоненты (Братья и сестры), которые получат магическое число с целью отображения его с помощью трех разных подходов:

Первый подход

Компонент ChildOfHome уважает каскадный поток реквизитов React и, учитывая, что целью является лишь показать магическое число, он отображает props получено напрямую.

DdFAz1VvRhbZ1vgJgoKYoguzuPEWRDsFkI-L

Второй подход

Компонент ChildOfHomeBrother получает props от своего отца и, вызывая componentDidMountустанавливает магическое число в state. Затем он предоставляет state.magicNumber.

Этот пример не работает, потому что render() не знает, что а prop изменился, поэтому он не запускает повторное воспроизведение компонента. Поскольку компонент больше не воспроизводится повторно, componentDidMount не вызывается и дисплей не обновляется.

gPNGY21whSekaZpxB2qWutfofEw96BwgAs6X

Третий подход

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

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

Это неправильно, если вам не нужно разрешить пользователю изменить полученное значение prop.

Если вам не нужно изменять значение prop, всегда старайтесь поддерживать работу в соответствии с потоком React (Первый подход).

Вы можете проверить рабочую веб-страницу по этому примеру, который я подготовил для вас в Glitch. Посмотрите и повеселитесь?

Также проверьте код в Home.js и HomeCodeCleaned.js (без материалов HTML) в моем репо об этой статье.

Как установитьState

Поэтому я думаю, что пора испачкать руки!

Давайте немного поиграем setState и улучшайте это! Просто следуйте и возьмите еще одну чашку кофе!

Давайте создадим небольшую форму для обновления данных пользователя:

7QEN8rHC9lVLP1YX2nyTVECC7s7G-25dDkjG
Небольшое упражнение на setState()

Вот код для примера выше:

YVqIxzftG-aQyjVeMvPwb5IPbpe7Xlq-C7ln
Первоначальный домашний компонент

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

Что делать, если мы создадим еще одно поле формы для ввода и отображения фамилии?

FaqdEOSaxiOvUvHwrdTjTI4DVr9icW3-40Dt
Функция фамилии
Jut4MxFFK81esqawr6NkqHWMsn4fNVWWfbzl
абстрактный handleFormChange

Хорошо! Мы абстрагировали handleFormChange метод, чтобы иметь возможность обрабатывать все поля ввода и setState.

Что делать, если мы добавим переключатель, чтобы пометить данные как действительные или недействительные, и счетчик, чтобы знать, сколько изменений мы внесли в состояние?

T52heLJjKgK8ziG6CcEuxjYDhc91qjdOxP1h
Снимок экрана, показывающий console.log состояния компонента
iu0Fdle1B1iFim6GZIKf8O6z3fgjHDn4h7qe
handleFormChange обновлен с обработчиками флажков и счетчиков

Да! Мы качаемся! Мы многое абстрагировали!

Хм… Скажем, я не хочу, чтобы флажок управлял isValid сменная, но простая кнопка переключения.

Давайте отделим обработчик счетчика от этого метода. Это хорошо работает, но в более сложных ситуациях, когда React нуждается в пакетных/групповых изменениях, не стоит полагаться на this.state.counter переменную, чтобы добавить еще одну. Это значение может изменяться без вашего ведома.

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

Давайте немного функциональны!

0p8DlnnaNpXtqPG81xTayly9J8VE2ibidKwK
Снимок экрана показывает переключатель действительный/недействительный и console.log переменной state.counter
C5veVluHRXO39bXkvVKgHCWuH6japAFj3D3R
разделение обработчиков контроля

Ладно — мы потеряли абстракцию, потому что отделили обработчики, но на это весомая причина!

Поэтому в это время мы сохраняем handleFormChange передача объекта в setState Метод API. Но handleCounter и handleIsValid Теперь методы функционируют и начинают с захвата текущего состояния, а затем в зависимости от этого состояния изменения его на следующее.

Это правильный способ изменения state переменных, зависящих от предыдущего состояния.

А если мы хотим console.log() изменения состояния firstName и lastName формы ввода каждый раз, когда происходит изменение? Давайте попробуем!

HUCXO8J0ASy4NNfDU1zZuEtXq-zpdiIQe1ZK
метод logFields().

Хорошо! Каждый раз handleFormChange происходит (что означает, что произошло новое нажатие клавиши). logFields() метод вызывается и регистрирует текущее состояние в консоли!

Давайте проверим консоль браузера:

jLz33AfgQi6kldAGYf4KT479Zr2ntt3-RBUk
снимок экрана console.log состояния имени и фамилии

Подождите! Что здесь произошло, люди? Журнал консоли – это одно изменение перед вводом текущей формы! Почему это происходит?

setState является асинхронным!!

Мы уже знали это, но теперь мы видим нашими глазами! Что там происходит? Давайте посмотрим на handleFormChange и logFields методы выше.

Итак, handleFormChange метод получает имя и значение события, а затем выполняет setState этих данных. Затем он вызывает handleCounter чтобы обновить информацию счетчика, и в конце вызывает logFields метод. The logFields метод захватывает currentState и возвращает Эдуард вместо Эдуардо.

Дело в том: setState является асинхронным и бездействует в данный момент. React выполняет свою работу и выполняет logFields метод сначала, оставляя setState для последующего цикла событий.

Но как мы можем избежать такой ситуации?

Ну, setState API имеет a callback чтобы избежать этой ситуации:

3wyO2ef7SMFdzVrxDGpTwJkXvdEV7wCZLGh2
метод setState API

Если мы хотим logFields() чтобы учесть последние изменения, которые мы внесли в состояние, нам нужно вызвать его внутри обратного вызова, например:

GPYFMLHBhIOkbjGGdfcDm5Uz24og0hvPYtvC
с помощью обработчика обратного вызова метода setState() API

Ладно, теперь это работает!

Мы говорим React: «Эй, React! Следите за этим, когда вы вызываете logFields метод Я хочу, чтобы вы имели state уже обновлено, хорошо? Я доверяю тебе!»

React говорит: «Хорошо, Эдо! Я собираюсь справиться со всеми этой партией вещей, которые я обычно делаю на заднем дворе вместе с setState вещь, и только когда я закончу с этим, я призываю logFields()! Крутой чувак! Расслабься!»

2YuGDOcmnseFY5lMTceR9FBGZ8h4friD-gnT
снимок экрана console.log() полного имени

И собственно сработало!

Хорошо всем! К этому времени мы справились с основными подводными камнями setState.

Хватит ли вам смелости выйти за стену? Возьмите чашечку кофе, и давайте по-настоящему гулять…

Станьте модным из setState()

Теперь, когда мы имеем handleCounter и handleIsValid методы и setState() Выраженные функциями, мы можем составить обновление состояния с другими функциями! Мне нравится композиция! Давай развлечемся!

pBcn25XBdxdA9uqPSqRXDRbRu6fdMB5MdS-4
абстрагирование handleIsValid

Мы можем принять логику внутрь setState к функции вне компонента класса. Назовем это toggleIsValid. ☝️

MQkXig9EC7Fem4-xeipehkq1KUJweQE027QD
Функция toggleIsValid

Теперь эта функция может существовать вне компонента класса в любом месте вашего приложения.

Что делать, если мы используем функцию высшего порядка?

AfGwofoy8ykA4pYHHr9cRiMSeUN9oEgH-yca
изменение toggleIsValid функцией высшего порядка

Вот Да! Теперь мы не призываем toggleIsValid больше функционировать. Мы вызываем абстрактную функцию высшего порядка, которая называется toggleKey и передача в него ключа (в данном случае строчки).

Как нам нужно изменить toggleIsValid функционировать сейчас?

YJ1jrcCACrvShq5Je8fZYWrxSfEodlZYWiDo
toggleKey функция высшего порядка

Что? Теперь у нас есть функция под названием toggleKey что получает a key и возвращает новую функцию, изменяющую состояние в соответствии с предоставленным ключом.

Это toggleKey может быть в библиотеке или вспомогательном файле. Его можно вызвать во многих разных контекстах, чтобы изменить состояние того, что вы хотите, на его противоположность.

Прекрасно!

Сделаем то же самое с обработчиком счетчика прироста:

nkgBbIQTNdFGZfTDtZkigh1HDMCWZBnnNii9
Абстракция handleCounter для вызова функции высшего порядка
oxRMcY3Kwj72HrWrE5IpNTDhlcb4mnaw8s44
incrementCounter-функция высшего порядка

Да! Это работает! Да мило. Давайте сейчас сходят с ума…

Съемка на Луну и возвращение

Что делать, если мы создадим генерик makeUpdater функция, получающая функцию преобразования, которую вы хотите применить, принимает ключ и возвращает функцию состояния, которая управляет состоянием с помощью функции преобразования и ключа? Немного запутались? Пойдем!

mKBYvEDHZDt1hhK-67J-yc7G9ciZd6ONEU37
makeUpdater-функция высшего порядка

Ладно, хватит… Давайте остановимся здесь. ?

Вы можете проверить весь код, сделанный в этом репозитории GitHub.

Последнее, но не последнее

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

Не забывайте setState является асинхронным.

Не забывайте setState может принимать объект или функцию

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

Библиография

  1. Документация React
  2. Reach Tech Courses Райана Флоренса, которые я очень рекомендую.

Спасибо большое!

Добавить комментарий

Ваш адрес email не будет опубликован.