Формы являются неотъемлемой частью любого современного применения. Они служат базовой средой для пользователей, чтобы взаимодействовать с вашим приложением. Разработчики полагаются на формы для всего: надежно регистрируют пользователь, поиск и фильтрацию списка продуктов, бронируя продукт и построение корзины и т. Д. Более сложные приложения, построенные для предприятий, обычно более интенсивны, с полями ввода, охватывающие несколько вкладок. Кроме того, вы должны рассмотреть логику проверки, которая должна быть развернута.
В этом руководстве мы собираемся посмотреть, как образуются обрабатывает реагирование. Мы рассмотрим не только основы, но и формируйте проверку и лучшие практики – даже опытные разработчики получают определенные детали не так.
Давайте начнем.
Создание формы – управляемого компонента против неконтролируемого компонента
РЕАКТ предлагает государственным, реактивным подходом к созданию форм. В отличие от других элементов DOM, элементы HTML-формы работают по-разному в реакции. Например, данные формы обычно обрабатываются компонентом, а не DOM, и обычно реализуются с использованием контролируемых компонентов. Изображение ниже идеально описывает, насколько управляемыми компонентами работают в реакции.
Структура формы аналогична тем, что обычные HTML-формы. Однако каждый входной элемент получает свой собственный компонент, который мы называем тупыми компонентами. Компонент контейнера отвечает за поддержание состояния. Разница в том, что мы используем функцию обратного вызова для обработки событий формы, а затем с использованием состояния контейнера для хранения данных форм. Это дает вашему компоненту лучше контролировать элементы управления форм и данные формы.
Функция обратного вызова срабатывает на событиях, включая изменение значений управления форм или на представлении формы. Затем функция толкает значения формы в локальное состояние компонента, а затем данные, которые следует контролировать компонентом. Поскольку мы используем атрибут Value на элементе формы, отображаемое значение будет иметь значение this.state.value
Отказ
Существует еще одна техника, широко известная как неконтролируемые компоненты для создания входных форм. Это больше похоже на традиционные HTML-формы, потому что данные входной формы хранятся внутри DOM, а не в компоненте. Элементы, как и
Поддерживать свое собственное состояние, которое они обновляют, когда входные значения меняются. Вы можете запрашивать DOM для значения входного поля с помощью Ref.
Вот пример из Официальные документы которые демонстрируют, как работают неконтролируемые компоненты.
class NameForm extends Component { constructor(props) { super(props); this.handleSubmit = this.handleSubmit.bind(this); } handleSubmit(e) { alert('The value is: ' + this.input.value); e.preventDefault(); } render() { return (); } }
Здесь Компонент несет ответственность за хранение его состояния. Атрибут REF создает ссылку на доступный узел DOM, и вы можете вытащить это значение, когда вам это нужно – когда вы собираетесь отправить форму в примере.
РЕАКТ рекомендует использовать контролируемые компоненты на Refs для реализации форм. Refs предлагают бэкдор до DOM, что может соблазнить вас использовать его, чтобы делать вещи. Управляемые компоненты, с другой стороны, более просты – данные формы обрабатываются компонентом реагирования. Однако, если вы хотите интегрировать реагировать с помощью неадгического проекта, или создать быструю и легкую форму по какой-то причине, вы можете использовать Ref
Отказ Остальная часть этого руководства будет сосредоточиться на контролируемых компонентах.
Реагистрационная форма демо
Вот демонстрация CodeSandobx для формы, которую мы будем создавать сегодня. @ Реагистрационная форма демо
Вы также можете взять копию кода из мой github repo Отказ Клонировать репо, запустить NPM установить
, а потом беги NPM начать
Отказ
Структурирование формы
Реактивная модель композиции позволяет Организовать свои компоненты реагирования в меньший многоразовый код. Каждый компонент существует как независимая функциональная единица, а также иерархия компонентов может быть использована для представления определенной функции. Эта структура особенно хорошо работает с формами. Вы можете создавать пользовательские компоненты для ,
,
и т. Д. И повторно используйте их, чтобы составить
Formcontainer
составная часть.
Примечание. Хотя вместо этого может быть заманчиво использовать библиотеку формы, шансы высоки, что вы можете столкнуться с препятствиями, когда вам нужно добавить пользовательское поведение и проверку. Создание многоразового компонента формы с царапины поможет вам поддержать ваше понимание реактивных форм.
import React, { Component } from 'react'; import './styles.css'; import FormContainer from './containers/FormContainer'; class App extends Component { render() { return (); } } export default App;React Form
FormContainer – это контейнерный компонент, который отображает все элементы формы и обрабатывает всю бизнес-логику. Мы называем это контейнерным компонентом, потому что оно заботится о обновлении состояния формы, представления формы обработки и создание вызовов/диспетчеризации API. Тупые компоненты или презентационные компоненты касаются того, как все выглядит и содержат фактическую разметку DOM. Эти компоненты получают данные и обратные вызовы исключительно как реквизиты. Я охватил больше об этом на моем Составные составляющие по сравнению с отсутствием бездействия в React руководство.
Давайте перейдем и создаем контейнер:
import React, {Component} from 'react'; /* Import Components */ import CheckBox from '../components/CheckBox'; import Input from '../components/Input'; import TextArea from '../components/TextArea'; import Select from '../components/Select'; import Button from '../components/Button' class FormContainer extends Component { constructor(props) { super(props); this.state = { newUser: { name: '', email: '', age: '', gender: '', expertise: '', about: '' }, genderOptions: ['Male', 'Female', 'Others'], skillOptions: ['Programming', 'Development', 'Design', 'Testing'] } this.handleFormSubmit = this.handleFormSubmit.bind(this); this.handleClearForm = this.handleClearForm.bind(this); } /* This life cycle hook gets executed when the component mounts */ handleFormSubmit() { // Form submission logic } handleClearForm() { // Logic for resetting the form } render() { return (); } } export default FormContainer; }
Во-первых, мы импортировали глупые компоненты из каталога компонентов. Компоненты включают ,
,
<Флажка>
, и
<Кнопка>
Отказ
Затем мы инициировали состояние для хранения пользовательских данных и данных пользовательского интерфейса. Два метода – Handleformsubmit ()
и handleclearform ()
– были созданы для обработки логики формы. Способ Render отображает все поля ввода и кнопки, необходимые для нашей формы регистрации.
Составляя тупые компоненты
Мы выложили структуру формы. Далее нам нужно сочинять детские компоненты. Давайте пройдемся через компоненты один за другим.
<Ввод/>
Компонент отображает однострочное входное поле. Тип ввода может быть либо текст или число. Давайте посмотрим на реквизиты, которые нам нужно создать <Ввод/>
составная часть.
Тип
–Тип
Определяет, отображает ли поле входного поля типа, текста или номера. Например, если значениеТип
равно номеру, то<ввод/>
будет оказана. В противном случае<ввод/>
получает.Название
– Значение типа заголовка будет отображаться как метка этого конкретного поля.Имя
– Это атрибут имени для ввода.ценность
– значение (текст или число), которое должно отображаться внутри поля ввода. Вы можете использовать этот опоры, чтобы дать значение по умолчанию.Зажигатель
– Дополнительная строка, которую вы можете пройти так, чтобы поля ввода отображается текст заполнителя.HandleChange
– функция управления, которая запускается при изменении значения элемента управления входным элементом. Затем функция обновляет состояние родительского компонента и передает новое значение через опору значение.
Вот код для <Ввод/>
составная часть. Обратите внимание, что мы используем нестандартные функциональные компоненты здесь.
const Input = (props) => { return () } export default Input;
Вы можете дополнительно расширить список возможных атрибутов и добавить их в качестве опоры. Вот как выглядит декларация компонента:
{/* Name of the user */}
HandleChange
Обратный вызов позаботится о обновлении состояния, а обновленное значение распространяется через ropps.value
Отказ Я собираюсь назвать функцию обратного вызова как ДЕРЕВОЧНОЕ ИМЕМ
Отказ
/* FormContainer.jsx */ //... handleFullName(e) { let value = e.target.value; this.setState( prevState => ({ newUser : {...prevState.newUser, name: value } })) } //...
SetState
принимает объект или функцию UPDATER со следующей подписью.
(prevState, props) => stateChange
Превзойти
Объект содержит современное значение предыдущего состояния. Мы собираемся объединить обновленные значения с предыдущим состоянием.
Примечание : В JavaScript методы класса не связаны по умолчанию. Вам нужно будет связать это вручную. Что это обозначает? Вам нужно будет добавить привязку в конструктор для каждого класса метода, и привязка будет выглядеть так:
this.handleFullName = this.handleFullName.bind(this)
В качестве альтернативы вы можете использовать классные поля делать обязательство за пределами конструктора. Функция все еще находится на экспериментальной фазе, поэтому вам нужно будет установить плагин Babel Свойства преобразования-класса для поддержки IT Отказ
Следующее поле ввода будет для возраста. Логика Обслуживание
будет похоже на ДЕРЕВОЧНОЕ ИМЕМ
метод.
/* FormContainer.jsx */ handleAge(e) { let value = e.target.value; this.setState( prevState => ({ newUser : {...prevState.newUser, age: value } }), () => console.log(this.state.newUser)) }
Этот метод обновляет состояние this.state.newuser.newus.age. Хотя этот подход в порядке, вы можете ревертировать код и создать универсальный метод обработчика, который работает для всех <Ввод/>
составные части.
/* FormContainer.jsx */ handleInput(e) { let value = e.target.value; let name = e.target.name; this.setState( prevState => { return { newUser : { ...prevState.newUser, [name]: value } } }, () => console.log(this.state.newUser) ) }
Руководство ()
заменит оба ХОРОШОЧНОСТЬ ()
и Одежда ()
Отказ Единственное изменение, которое мы сделали, состоит в том, чтобы извлечь значение имени из переменной формы, а затем использовать эти данные для установки состояния. Таким образом, значение опор имени должно быть таким же, как ключ имущества в состоянии.
Далее, <Выбор/>
Отказ
<Выбор/>
<Выбор/>
Компонент отображает список раскрывающихся элементов. Обычно будет текст заполнителя или значение по умолчанию для выпадания. Вот реквизиты для <Выбор/>
:
Название
– Значение оперения заголовка отображается как ярлыкэлемент.
Имя
– атрибут имени дляэлемент.
Варианты
– массив имеющихся вариантов. Например, мы используем<Выбор/>
Для отображения раскрывающегося списка гендерных параметров.ценность
– Опытка значения может быть использована для установки значения по умолчанию поля.Зажигатель
– короткая строка, которая заполняет первую<опция>
тег.HandleChange
– функция управления, которая запускается при изменении значения элемента управления входным элементом. Затем функция обновляет состояние родительского компонента и передает новое значение через опору значение.
Давайте посмотрим на фактический код для <Выбор/>
составная часть.
/*Select.jsx*/ const Select = (props) => { return() } export default Select;
Первый тег на опции заполняется строкой заполнителя. Остальные варианты отображаются из массива, который мы передали как реквизиты. При использовании метода карты для итерации через DOM-элементы, не забудьте добавить ключ
атрибут, который уникален. Это помогает отреагировать отслеживать обновления DOM. Если вы оставите ключ
Атрибут, вы увидите предупреждение в вашем браузере и мог столкнуться с проблемами производительности по дороге.
Теперь давайте посмотрим на функцию обратного вызова. Логика для метода аналогична для общего руления, который мы создали ранее. Мы можем на самом деле подключить этот метод обработчика как опоры, и все должно работать, как ожидалось.
{/* Age Selection */}
<Флажок/>
Флажки могут появиться немного сложнее, поскольку задействованы массивы. Но оба <Флажка>
и похожи с точки зрения реквизита. Основная разница заключается в том, как государство обновляется. Давайте сначала посмотрим на реквизиты.
Название
– уже покрыты.Имя
– уже покрыты.Варианты
– массив имеющихся вариантов. Массив обычно состоит из строк, которые в конечном итоге являются ярлыком и значением каждого флажка.Выделенные формы
– массив выбранных значений. Если пользователь выбрал определенный выбор заранее, массив выделения будет заполнен этими значениями. Это синонимичный для опоры компонента Component.HandleChange
– уже покрыты.
Вот компонент флажки.
/* CheckBox.jsx */ const CheckBox = (props) => { return(); }{props.options.map(option => { return ( ); })}
Линия проверено = {roppssselectedOptions.indexof (опция)> -1}
может быть запутанным, если вы никогда не использовали JavaScript’s Индекс
метод раньше. Индекс
Проверяет, существует ли конкретный элемент в массиве и возвращает его индекс. Предполагая, что опция содержит строку, она проверяет, существует ли строка в Выделенные формы
И если элемент не существует в массиве, он вернется -1. Это самый простой способ заполнить значения в группу флажков в форме.
Поскольку нам нужно подтолкнуть массив в состояние, что более сложно, чем обычный Руководство ()
Давайте создадим новый метод для обработки флажков.
handleSkillsCheckBox(e) { const newSelection = e.target.value; let newSelectionArray; if(this.state.newUser.skills.indexOf(newSelection) > -1) { newSelectionArray = this.state.newUser.skills.filter(s => s !== newSelection) } else { newSelectionArray = [...this.state.newUser.skills, newSelection]; } this.setState( prevState => ({ newUser: {...prevState.newUser, skills: newSelectionArray } }) ) }
Пользователь может взаимодействовать с флажком двумя способами – проверьте элемент или снимите флажок существующий элемент. Это взаимодействие пользователя соответствует двум действиям – добавляя элемент в массив или удаление существующего элемента из массива.
газету
Переменная имеет значение вновь выбранного (или измененного) элемента. Мы сравниваем его с существующим выбором предметов, хранящихся в this.state.newuser.skills
Отказ Мы снова собираемся полагаться на Индекс
Чтобы проверить, хранятся ли строка в газету
уже из массива. Если это часть массива, условие падает истина, а новый элемент выбора отфильтровывается и хранится в газете. В противном случае элемент информационного выбора объединяется в массив с использованием оператора распространения.
Наконец, состояние обновляется с использованием this.setState
Отказ
Я собираюсь оставить это как упражнение для читателя. Это довольно похоже на <Ввод/>
Компонент, который мы создали ранее. Элемент должен принимать дополнительные реквизиты для рядов и столбцов. Код для
Textarea
Компонент доступен в Demo Sandbox для справки.
<Кнопка/>
Кнопки проще всего простые. Вы можете сохранить <КНОПКА/>
Компонент довольно простой и легкий. Вот список реквизитов, которые требуется кнопка:
Название
– Текст для кнопки.Действие
– Функция обратного вызоваСтиль
– Объекты стиля могут быть переданы как реквизиты.
Вот …| <КНОПКА/> в действии:
/*Button.jsx */ const Button = (props) => { console.log(props.style); return( ) } export default Button;
Форма действия – HandleClearForm и DisingFormsubmit
Мы почти достигли конца туннеля. Последний шаг состоит в том, чтобы составить действия формы. Поскольку компонент FormContainer поддерживает состояние, методы действий формы пойдут туда.
handleclearform
Метод очистит состояние и установит его обратно к его начальным значениям.
handleClearForm(e) { e.preventDefault(); this.setState({ newUser: { name: '', age: '', gender: '', skills: [], about: '' }, }) }
Линия E.PreventDefault ()
Предотвращает обновленную страницу на представлении формы, которая является поведением форм по умолчанию.
Handleformsubmit ()
Метод заботится о том, чтобы сделать запросы AJAX на сервер. Данные, которые должны быть отправлены, доступна в этой. Newuser. Есть много библиотек, которые вы можете использовать для создания вызовов AJAX. Я собираюсь использовать здесь.
handleFormSubmit(e) { e.preventDefault(); let userData = this.state.newUser; fetch('http://example.com',{ method: "POST", body: JSON.stringify(userData), headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, }).then(response => { response.json().then(data =>{ console.log("Successful" + data); }) }) }
Это оно!
Резюме
В этой статье мы покрыли все, что вам нужно знать о строительных формах в реакции. Реакция обладает компонентной архитектурой, а компоненты предназначены для многоразового использования. Мы прошли вперед и создали компоненты для входных элементов, таких как: <ввод/>
, <Выбор/>
, и т. Д. Вы можете дополнительно настроить компоненты в соответствии с вашими требованиями, проходящие больше реквизитов.
Я надеюсь, что у вас был хороший читать. Каковы ваши мысли о строительных формах, использующих реагирование? Если вам есть что поделиться, дайте нам знать в комментариях.