Простая валидация форм в ReactJS


Валидация форм в ReactJS | How to do Simple Form Validation in Reactjs

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

Полный код можно посмотреть здесь и запустить приложение в Heroku.

Мы будем использовать create-react-app для создания и запуска просто приложения с использованием React.

Установим пакеты и создадим новое приложение:

$ npm install -g create-react-app 
$ create-react-app react-form-validation-demo

Запустим приложение:

$ cd react-form-validation-demo/
$ npm start

Откроем созданное приложение по ссылке http://localhost:3000/

Подключим Bootstrap для удобной стилизации будущей формы:

$ npm install react-bootstrap — save 
$ npm install bootstrap@3 — save

В начале файла src/index.js импортируем файл стилей CSS Bootstrap и, опционально, тему Bootstrap:

import ‘bootstrap/dist/css/bootstrap.css’; 
import ‘bootstrap/dist/css/bootstrap-theme.css’;

Хорошо. Теперь построим основу нашего приложения—добавим компонент Form.

В src/App.js заменяем первоначальную разметку с помощью компонента Form, который вскоре создадим. Также необходимо сделать импорт компонента:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Form from './Form.js';
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>React Form Validation Demo</h2>
</div>
<Form /> // компонент формы
</div>
);
}
}
export default App;

Создадим компонент Form в src/Form.js. Мы сделаем простую форму с полями для ввода электронной почты и пароля. Добавим кнопку отправки формы.

import React, { Component } from ‘react’;
import ‘./Form.css’;
class Form extends Component {
render () {
return (
<form className=”demoForm”>
<h2>Sign up</h2>
<div className=”form-group”>
<label htmlFor=”email”>Email address</label>
<input type=”email” className=”form-control”
name=”email” />
</div>
<div className=”form-group”>
<label htmlFor=”password”>Password</label>
<input type=”password” className=”form-control”
name=”password” />
</div>
<button type=”submit” className=”btn btn-primary”>
Sign up
</button>
</form>
)
}
}
export default Form;

Я копировал пример формы из примера в Bootstrap, так как она смотрится довольно неплохо.

Но я сделал некоторые изменения, чтобы форма работала с JSX. Так слова class и for зарезервированы в JavaScript, поэтому мы должны использовать className и htmlFor взамен них, соответственно.

Также необходимо убедиться, что все теги закрыты, включая input .

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

constructor (props) {
super(props);
this.state = {
email: '',
password: ''
}
}

Мы установили значения по умолчанию emailи passwordв виде пустых строк.

Подключим поля вводя к значениям state , для почты:

value={this.state.email}

и пароля:

value={this.state.password}

Если мы сейчас будем вводить текст в поля, то значение состояния компонента не будет обновляться. Добавим обработчик onChange для полей ввода:

onChange={this.handleUserInput}

Добавим логику обработчика:

handleUserInput = (e) {
const name = e.target.name;
const value = e.target.value;
this.setState({[name]: value});
}

Отлично. Теперь перейдем к самой проверке.

Будем хранить сообщения и код ошибок при вводе данных в state. Добавим несколько свойств для первоначального состояния:

constructor (props) {
super(props);
this.state = {
email: '',
password: '',
formErrors: {email: '', password: ''},
emailValid: false,
passwordValid: false,
formValid: false
}
}

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

Также еще добавили три свойства типа booleanemailValid, passwordValid, formValid , которые зависят от валидации отдельного поля и активности кнопки для отправки формы. Установим эти значения по умолчанию в false.

Добавим новый компонент FormErrors для отображения ошибок валидации над формой:

<div className=”panel panel-default”>
<FormErrors formErrors={this.state.formErrors} />
</div>

Сохраним компонент в файле src/FormErrors.js:

import React from ‘react’;
export const FormErrors = ({formErrors}) =>
<div className='formErrors'>
{Object.keys(formErrors).map((fieldName, i) => {
if(formErrors[fieldName].length > 0){
return (
<p key={i}>{fieldName} {formErrors[fieldName]}</p>
)
} else {
return '';
}
})}
</div>

Это простой функциональный компонент, который принимает объект formError и возвращает объект содержащий JSX с сообщениями об ошибке, либо пустую строку.

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

Метод setState принимает функцию обратного вызова в качестве второго аргумента, в которую можно передать функцию проверки:

handleUserInput (e) {
const name = e.target.name;
const value = e.target.value;
this.setState({[name]: value},
() => { this.validateField(name, value) });
}

Объявим эту функцию:

validateField(fieldName, value) {
let fieldValidationErrors = this.state.formErrors;
let emailValid = this.state.emailValid;
let passwordValid = this.state.passwordValid;
switch(fieldName) {
case 'email':
emailValid = value.match(/^([\w.%+-]+)@([\w-]+\.)+([\w]{2,})$/i);
fieldValidationErrors.email = emailValid ? '' : ' is invalid';
break;
case 'password':
passwordValid = value.length >= 6;
fieldValidationErrors.password = passwordValid ? '': ' is too short';
break;
default:
break;
}
this.setState({formErrors: fieldValidationErrors,
emailValid: emailValid,
passwordValid: passwordValid
}, this.validateForm);
}
validateForm() {
this.setState({formValid: this.state.emailValid &&
this.state.passwordValid});
}

Здесь мы имеем две проверки. Для поля электронной почты проверка осуществляется при помощи регулярного выражения.

Отмечу: я использую пример регулярного выражения из Devise library. Проверка электронной почты достаточно сложная задача, но для нашего примера этого будет достаточно.

Поле для ввода пароля проверяем на количество введенных символов. Минимальное количество 6 символов. Если менее, то выдаем ошибку.

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

Затем вызываем setState для обновления formErrors и свойства прохождения проверки ( emailValid или passwordValid ). Далее отправляем функцию обратного вызова validateForm для установки значения formValid .

Добавить атрибут disable для кнопки отправки. Значение атрибута зависит от значения formValid в state .

<button type="submit" className="btn btn-primary"
disabled={!this.state.formValid}>Sign up</button>

Теперь наша простая форма будет иметь проверку ввода данных.

Можно немного улучшить форму, добавив подсветку поля, которое не прошло валидацию. Для этого добавим полю класс Bootstraphas-error в добавок в классу form-group . 

<div className={`form-group
${this.errorClass(this.state.formErrors.email)}`}>

Метод errorClass определим как:

errorClass(error) {
return(error.length === 0 ? '' : 'has-error');
}

Теперь поле не прошедшее проверку получает красное обрамление вокруг.

Как-то так.

Простая валидация форм в ReactJS

Вы можете посмотреть итоговый код и запустить тестовое приложение на Heroku.

Это очень просто пример. Мы имеем жесткое название полей при валидации, что вызовет проблемы при масштабировании приложения. Также мы имеет только одну проверку поля, что не совсем удобно.

Но мы можем обобщить это (уйти от жесткой привязки к поляи?—?прим. переводчика), чтобы обрабатывать любое количество полей с множественными ошибками.

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

Этот урок является отрывком The Complete React on Rails Course, в котором разъясняется валидация форм более подробно.

Перевод статьи How to do Simple Form Validation in Reactjs

15.03.2017 Эту страницу просмотрели за все время 11663 раз(а)


Twitter


Облако тегов