Валідація форм в React

Якщо ви коли-небудь користувалися фреймворком AngularJS, то ви знаєте, як легко в ньому валидируются форми. Однак у React ситуація дещо гірша. Воно і зрозуміло, адже це всього лише бібліотека. Але завдяки спільноті з цієї бібліотеки можна зробити потужний засіб для створення повноцінних SPA-додатків. На даний момент створено безліч компонентів, які здатні задовольнити більшість потреб розробників на React. У даній статті я б хотів описати підхід, який використовував для валідації форм з допомогою компонента Formsy-react.

Почну з того, що компонентів для валідації форм існує досить багато (тут представлено 32). Я спробував деякі з них і вирішив зупинитися саме на Formsy, так як він виглядав не надто замудреным і при цьому досить гнучким. Принцип роботи я покажу на прикладі форми логіна. Щоб не заморочуватися зі стилями, будемо використовувати react-bootstrap.

У тестовому додатку логін можливий 3 способами: за логіном, електронною поштою або номером телефону. Відповідно, для кожного виду логіна потрібні свої конкретні валідації. Для простоти прикладу, я покажу лише компонент з формою логіна, посилання на репозиторій проекту ви зможете знайти в кінці статті.

Отже, у нас є компонент Login, який і відповідає за нашу форму. У ньому є 3 різних способу логіна, відповідно, зручно було б відобразити їх за допомогою вкладок:

Вихідний код вкладок з полями введення
<Tab.Pane eventKey="login">
<Formsy.Form onValidSubmit={this.handleLogin} onValid={this.enableButton} onInvalid={this.disableButton}>

<FormGroup>
<ControlLabel>Login</ControlLabel>
<TextInput name="login" type="text" validations={{minLength: 5}} validationErrors={{minLength: 'Enter at least 5 sumbols'}} required/>
</FormGroup>

<FormGroup>
<ControlLabel>Password</ControlLabel>
<TextInput name="loginPassword" type="password" validations={{strongPassword: validations.strongPassword}} validationErrors={{strongPassword: "Enter a strong password! At least 6 symbols"}} required/>
</FormGroup>

<FormGroup>
<Button type="submit" bsStyle="primary" disabled={!this.state.isButtonEnabled} block>Login</Button>
</FormGroup>

</Formsy.Form>
</Tab.Pane>

<Tab.Pane eventKey="email">
<Formsy.Form onValidSubmit={this.handleLogin} onValid={this.enableButton} onInvalid={this.disableButton}>

<FormGroup>
<ControlLabel>Email</ControlLabel>
<TextInput name="email" type="text" validations={{isGoogleEmail: validations.isGoogleEmail}} validationErrors={{isGoogleEmail: 'Only Gmail boxes are accepted'}} required/>
</FormGroup>

<FormGroup>
<ControlLabel>Password</ControlLabel>
<TextInput name="loginPassword" type="password" validations={{strongPassword: validations.strongPassword}} validationErrors={{strongPassword: "Enter a strong password! At least 6 symbols"}} required/>
</FormGroup>

<FormGroup>
<Button type="submit" bsStyle="primary" disabled={!this.state.isButtonEnabled} block>Login</Button>
</FormGroup>

</Formsy.Form>
</Tab.Pane>

<Tab.Pane eventKey="phone">
<Formsy.Form onValidSubmit={this.handleLogin} onValid={this.enableButton} onInvalid={this.disableButton}>

<FormGroup>
<ControlLabel>Phone</ControlLabel>
<TextInput name="phone" type="tel" validations={{isPhoneNumber: validations.isPhoneNumber, containsPlusPrefix: validations.containsPlusPrefix}} validationErrors={{isPhoneNumber: 'You should enter a valid phone number', containsPlusPrefix: 'Enter your number without +'}} required/>
</FormGroup>

<FormGroup>
<ControlLabel>Password</ControlLabel>
<TextInput name="phonePassword" type="password" validations={{strongPassword: validations.strongPassword}} validationErrors={{strongPassword: "Your password should contain at least 1 number, 1 lowercase letter, 1 uppercase letter"}} required/>
</FormGroup>

<FormGroup>
<Button type="submit" bsStyle="primary" disabled={!this.state.isButtonEnabled} block>Login</Button>
</FormGroup>

</Formsy.Form>
</Tab.Pane>


Кожна вкладка представляє з себе форму, всередині якої лежить 2 поля і кнопка для відправки форми.

Почнемо по порядку, з компонента Formsy.Form. У ньому нас цікавить 3 властивості (props): onValidSubmit, onValid, onInvalid.

Властивість onValidSubmit відповідає за відправку форми. Якщо всі дані введені коректно і користувач натискає кнопку логін, то відбувається виклик функції this.handleLogin, яка відправляє дані на сервер. Ця функція повинна мати один параметр, який буде містити в собі об'єкт. В цьому об'єкті зберігаються назви полів та їх значення.

Властивості onValid і onInvalid відповідають за стан кнопки відправки. У них варто передати функцію, яка буде включати або вимикати кнопку в залежності від коректності введених даних.

Далі у нас є поля, які необхідно перевіряти на валідність введених даних. Для нормального функціонування даного компонента, нам необхідно створити власний компонент для введення даних (TextInput). На сайті Formsy можна знайти на готовий компонент, який включає в себе все що потрібно і вимагає мінімум змін перед використанням. В наш компонент необхідно передати всі стандартні властивості тега input, такі як type і пр, а також кілька спеціальних властивостей, які допоможуть з валідацією компонента.

Першим таким властивістю є name. Коли користувач натисне на кнопку відправки даних, ви зможете легко отримати потрібний input по імені, а також його значення.

Також необхідно позначити властивість validations. В даному властивості очікується об'єкт. У компоненті Formsy вже закладені деякі валідації, наприклад, minLength, яку я використовував в полі логін. Не складно здогадатися, що з допомогою цієї перевірки ми можемо встановити мінімальне число введених символів. Є і багато інших вбудованих валідації, наприклад, на перевірку коректності адреси електронної пошти, телефону та інші. Однак, цей компонент не був би такий гарний, якби не можна було створювати власні функції перевірки. І це можливо!

Наприклад, у полі з введенням електронної пошти я оголосив власну перевірку того, що людина вводить адресу електронної пошти, зареєстрований на gmail.com. Функція перевірки виглядає наступним чином:

Вихідний код функції перевірки
function isGoogleEmail(values, value) {
if (typeof value !== 'undefined' && value.indexOf('gmail.com') === -1) {
return false;
}
return true;
}


Функція приймає в себе 2 параметра: всі поля форми і поточне поле, яке проходить перевірку. Перший параметр містить масив всіх полів та їх значень, які присутні у формі. У другому параметрі value міститься вміст поточного поля. Всередині функції обов'язково потрібно перевірити, чи існує value, а також здійснити будь-які інші перевірки. Якщо функція повертає false, значить перевірка не пройшла, і користувач не зможе відправити форму. У зворотному випадку все ок, дане поле пройшло перевірку і не містить помилок

Друге властивість, яке ми повинні передати в полі вводу — validationErrors. Вся принадність цієї властивості в тому, що для кожної помилки воно буде видавати своє повідомлення. Таким чином, можна повісити на одне поле різні перевірки (наприклад, кількість введених символів, наявність хоча б одного спеціального символу і пр) і для кожної з цих перевірок видавати свою помилку (а не писати в одному повідомленні про те, що поле повинно містити щонайменше 8 символів, 2 цифри, 3 літери тощо). Даний підхід використовується у поле для введення телефону, де спочатку відбувається «супер надійна перевірка на те, що введений текст дійсно є телефоном, а потім перевіряється, чи не варто початку '+'.

Таким чином, даний компонент здорово допомагає з валідацією форм, якої так не вистачає в React. Повний код даного прикладу ви можете подивитися це репозиторії, а також не забудьте подивитися в репозиторій Formsy, там ще дуже багато всього цікавого. Надіюсь, що стаття допоможе вам при створенні вашого додатка.

Спасибі за увагу!
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.