Статьи

Быстро реагируем: как работать с формами в React

Как работать с формами в React — это отрывок из React Quickly , практической книги Азата Мардана для всех, кто хочет быстро изучить React.js.

В этой статье рассказывается, как захватить ввод и ввод текста с помощью других элементов формы, таких как input, textarea и option. Работа с ними имеет первостепенное значение для веб-разработки, поскольку они позволяют нашим приложениям получать данные (например, текст) и действия (например, клики) от пользователей.

Исходный код для примеров в этой статье находится в папке ch07 репозитория GitHub azat-co / реакции-быстро . Некоторые демонстрации можно найти по адресу http://reactquickly.co/demos .

Если вам понравился этот пост, вам также может понравиться наш курс Build React Forms с Redux .

Рекомендуемый способ работы с формами в React

В обычном HTML, когда мы работаем с элементом ввода, DOM страницы поддерживает значение этого элемента в своем узле DOM. Получить доступ к значению можно с помощью таких методов, как document.getElementById('email').value или с помощью методов jQuery. DOM — это наше хранилище.

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

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

React — это простота использования декларативных стилей для описания пользовательских интерфейсов. React описывает пользовательский интерфейс, его конечную стадию и как он должен выглядеть.

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

Если разработчики предпочитают не поддерживать состояние компонента (в JavaScript) или не синхронизировать его с представлением, то это добавляет проблемы: может возникнуть ситуация, когда внутреннее состояние и представление различаются. Реакт не будет знать об измененном состоянии. Это может привести к всевозможным неприятностям и смягчает простую философию React. Лучше всего держать React render() как можно ближе к реальному DOM, что включает в себя данные в элементах формы.

Рассмотрим этот пример поля ввода текста. React должен включить новое значение в свой метод render() для этого компонента. Следовательно, нам нужно установить значение для нашего элемента на новое значение, используя value . Если мы реализуем поле <input> как мы всегда это делали в HTML, React будет поддерживать render() синхронно с реальным DOM. React не позволит пользователям изменять значение. Попробуй сам. Это сводит меня с ума, но это подходящее поведение для React!

 render() { return <input type="text" name="title" value="Mr." /> } 

Код выше представляет представление в любом состоянии, и значение всегда будет «Mr.». С полями ввода они должны меняться в ответ на нажатия клавиш пользователем. Учитывая эти моменты, давайте сделаем значение динамическим.

Это лучшая реализация, потому что она будет обновлена ​​из состояния:

 render() { return <input type="text" name="title" value={this.state.title} /> } 

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

 handleChange(event) { this.setState({title: event.target.value}) } render() { return <input type="text" name="title" value={this.state.title} onChange={this.handleChange.bind(this)}/> } 

Учитывая эти моменты, для разработчиков лучше всего реализовать следующие вещи для синхронизации внутреннего состояния с представлением (рисунок 1):

  1. определить элементы в render() используя значения из состояния
  2. захватывать изменения элемента формы, используя onChange() когда они происходят
  3. обновить внутреннее состояние в обработчике событий
  4. сохранить новые значения в состоянии, а затем обновить представление с новым render ()
Формы в React, рисунок 1: захват изменений во входных данных и применение к состоянию

Рисунок 1: Захват изменений на входе и применение к состоянию

На первый взгляд это может показаться большой работой, но я надеюсь, что, используя React больше, вы оцените этот подход. Это называется односторонним связыванием , потому что состояние только меняет представления. Там нет поездки обратно, только в одну сторону от государства до вида. При односторонней привязке библиотека не будет обновлять состояние (или модель) автоматически. Одним из основных преимуществ односторонней привязки является то, что она устраняет сложность при работе с большими приложениями, где многие представления могут неявно обновлять многие состояния (модели данных) и наоборот — рисунок 2.

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

Формы в React, рисунок 2: односторонняя или двусторонняя привязка

Рисунок 2: одностороннее или двустороннее связывание

И наоборот, двусторонняя привязка позволяет представлениям автоматически изменять состояния без явной реализации разработчиками. Двухстороннее связывание — это то, как работает Angular 1. Интересно, что Angular 2 заимствовал концепцию одностороннего связывания из React и сделал ее настройкой по умолчанию (вы все равно можете явно иметь двустороннее связывание).

Рекомендуемые курсы

Тодд девиз
Конечный ресурс для изучения Angular и его экосистемы. Используйте код купона «SITEPOINT» при оформлении заказа, чтобы получить скидку 25% .

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

До сих пор мы изучили лучший метод работы с полями ввода в React, который заключается в том, чтобы зафиксировать изменение и применить его к состоянию, как показано на рисунке 1 (ввод в измененное представление). Далее давайте посмотрим, как мы определяем форму и ее элементы.

Определение формы и ее событий в действии

Начнем с элемента <form> . Как правило, мы не хотим, чтобы наши входные элементы зависали случайным образом в DOM. Это может плохо работать, если у нас много функционально разных наборов входных данных. Вместо этого мы обертываем элементы ввода, которые имеют общую цель, в элемент <form></form> .

Наличие оболочки <form> не обязательно. Совершенно нормально использовать элементы формы в простых пользовательских интерфейсах. В более сложных пользовательских интерфейсах разработчики могут иметь несколько групп элементов на одной странице. В этом случае целесообразно использовать <form> для каждой группы. React <form> отображается в HTML <form> , и все правила, которые у нас есть, применяются также и к элементу React <form> . Согласно спецификации HTML5 , разработчики не должны вкладывать формы (это говорит о том, что контент является потоковым контентом, но без потомков элемента <form> ).

Сам элемент формы может иметь события. React поддерживает три события для форм в дополнение к стандартным событиям React DOM:

  • onChange : срабатывает при изменении любого из элементов ввода формы.
  • onInput : срабатывает при каждом изменении значений элементов <textarea> и <input> . Команда React не рекомендует использовать его (см. Ниже).
  • onSubmit : срабатывает при onSubmit формы, обычно нажатием Enter .

onChange против onInput

React onChange срабатывает при каждом изменении, в отличие от события изменения DOM , которое может срабатывать не при каждом изменении значения, а при потере фокуса. Например, для <input type="text"> пользователь может печатать без onChange и только после того, как пользователь нажимает onChange Tab или щелкает мышью на другом элементе (потерял фокус), onChange запускается в HTML (обычный событие браузера). Как упоминалось ранее, в React onChange срабатывает при каждом нажатии клавиши, а не только при потере фокуса.

С другой стороны, onInput в React является оболочкой для onInput DOM, который запускается при каждом изменении. Команда React рекомендует использовать onChange onInput .

Суть в том, что onChange React работает иначе, чем onChange в HTML, в том, что он более последовательный (и больше похож на onInput HTML). onChange срабатывает при каждом изменении, а не при потере фокуса.

Рекомендуемый подход в React — использовать onChange и использовать onInput только onInput когда вам нужно получить доступ к собственному поведению для события onInput . Причина в том, что поведение оболочки onChange React обеспечивает согласованность.

Реагировать на события

В дополнение к трем событиям, перечисленным выше, у <form> могут быть стандартные события React, такие как onKeyUp или onKeyUp . Использование событий формы может пригодиться, когда нам нужно захватить определенное событие для всей формы (группа элементов ввода).

Например, это хороший UX, позволяющий пользователям отправлять данные при нажатии enter (при условии, что вы не находитесь в поле textarea, в этом случае enter должен создать новую строку). Мы можем прослушать событие отправки формы, создав прослушиватель событий, который вызывает this.handleSubmit() .

 handleSubmit(event) {} render() { <form onSubmit={this.handleSubmit}> <input type="text" name="email" /> </form> } 

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

Как напоминание, не вызывайте метод (не используйте скобки) и не используйте двойные кавычки вокруг фигурных скобок (правильный путь: EVENT={this.METHOD} ) при установке обработчика события. Я знаю, что для некоторых читателей это простой JavaScript и простой, но вы не поверите, сколько раз я видел ошибки, связанные с этими двумя недоразумениями в коде React: мы передаем определение функции, а не ее результат, и мы используем curly фигурные скобки как значения атрибутов JSX.

Другой способ реализовать onKeyUp формы при вводе — вручную прослушать событие key up ( onKeyUp ) и проверить код ключа (13 для ввода ).

 handleKeyUp(event) { if (event.keyCode == 13) return this.sendData() } render() { return <form onKeyUp={this.handleKeyUp}> ... </form> } 

Обратите внимание, что метод sendData реализован где-то еще в коде. Также нам нужно bind(this) обработчик событий в constructor() .

Подводя итог, мы можем иметь события в элементе формы, а не только в отдельных элементах формы.

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


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