Формы и валидация в Ionic React

Формы и валидация в Ionic React
Ionic Framework обеспечивает первоклассную поддержку для создания быстрых и оптимизированных под мобильные устройства приложений для любой платформы с использованием React. Изучив это руководство, вы узнаете, как создавать формы при работе с Ionic React и как сделать данные формы интерактивными, добавив правила валидации с полезными текстовыми подсказками.

Ionic Framework — это набор инструментов пользовательского интерфейса, предназначенный для создания кроссплатформенных мобильных приложений с использованием HTML, CSS и JavaScript. Релиз Ionic 5, состоявшийся в начале 2020 года сопровождался официальной поддержкой React, что позволило React- разработчикам с легкостью создавать мобильные приложения с использованием привычных инструментов. Однако в нем не так отлично поддерживается работа с формами, и многие из существующих библиотек, предназначенных для создания форм в экосистеме React, плохо работают с компонентами Ionic Framework.

В этом руководстве рассказывается о том, как создавать формы с использованием компонентов ввода пользовательского интерфейса Ionic React. Изучив его, вы также узнаете, как использовать данную библиотеку для обнаружения изменений ввода формы и реагирования на правила валидации. Наконец, вы научитесь делать формы доступными для программ чтения с экрана, добавляя полезный текст в атрибуты ARIA.

Компоненты формы Ionic

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

Ionic предлагает готовые компоненты для работы с формами — некоторые из которых включают в себя IonItem, IonLabel, IonInput, IonCheckbox и IonRadio. Мы можем комбинировать данные компоненты для создания стандартных форм, не добавляя стили самостоятельно.

К примеру, приведенный ниже код:

<form className="ion-padding"> <IonItem> <IonLabel position="floating">Username</IonLabel> <IonInput /> </IonItem> <IonItem> <IonLabel position="floating">Password</IonLabel> <IonInput type="password" /> </IonItem> <IonItem lines="none"> <IonLabel>Remember me</IonLabel> <IonCheckbox defaultChecked={true} slot="start" /> </IonItem> <IonButton className="ion-margin-top" type="submit" expand="block"> Login </IonButton></form>

формирует форму входа в систему, которая выглядит следующим образом:

Формы и валидация в Ionic ReactСтандартная форма входа на iOS

По умолчанию компоненты формы Ionic хорошо смотрятся на iOS или Android, но они могут быть громоздкими, если вы работаете с React. Как и в случае с большинством инструментов в экосистеме React, вам необходимо решить, как вы планируете создавать формы, когда речь идет о функциональности и доступности — и то, и иное не менее важно, чем дизайн.

Хотя на выбор доступно много хелперов форм React, большинство из них не работают с компонентами форм Ionic. Я подозреваю, что основная причина этого заключается в том, что событие срабатывает при изменении значения поля ввода в Ionic onIonChange, тогда как большинство существующих библиотек форм прослушивают onChange.

Формы и валидация в Ionic ReactСобытие изменения срабатывает при изменении поля ввода

React Hook Form: небольшая и быстрая библиотека форм React

К счастью, это не так уж и плохо. Недавно я наткнулся на React Hook Form(RHF), библиотеку для работы с формами в React-проектах. Она обеспечивает поддержку контролируемых или неконтролируемых компонентов и проверку ввода, а API основан на хуках, так что данная библиотека работает только с функциональными компонентами.

На мой взгляд, самая привлекательная функцию для разработчиков, использующих Ionic React — это компонент <Controller /> — оболочка, которую он предлагает для работы с управляемыми компонентами. Компонент имеет в себя свойство onChangeName, которое можно использовать для указания имени события изменения для любого экземпляра компонента, который вы ему передаете. В следующих разделах я покажу вам, как это упрощает работу с формами в Ionic.

Создание формы регистрации

Давайте посмотрим, как RHF может помочь с функционалом формы, когда мы создаем в Ionic регистрационную форму. Если вы используете последнюю версию Ionic CLI(запустите npm i -g @ionic/cli для подтверждения), запустите новое приложение Ionic с React, выполнив приведенную ниже команду:

ionic start myApp blank --type=react

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

Примечание. Перед тем, как продолжить работу с данным руководством, вы должны удалить компонент ExploreContainer и его импорт в Home.tsx.

Чтобы начать работу с формой, установите пакет React Hook Form, выполнив приведенную ниже команду в корневом каталоге проекта:

yarn add react-hook-form

Это сделает библиотеку React Hook Form доступной в проекте. Создадим поле ввода ввода формы при помощи данной библиотеки. Откройте файл Home.tsx и замените его содержимое следующим:

import { IonContent, IonPage, IonText, IonItem, IonLabel, IonInput, IonButton } from "@ionic/react";import React from "react";import "./Home.css";import { Controller, useForm } from 'react-hook-form';const Home: React.FC =() => {  const { control, handleSubmit } = useForm();  const registerUser =(data) => {    console.log('creating a new user account with: ', data);  }  return(    <IonPage>      <IonContent className="ion-padding">        <IonText color="muted">          <h2>Create Account</h2>        </IonText>        <form onSubmit={handleSubmit(registerUser)}>          <IonItem>            <IonLabel position="floating">Email</IonLabel>            <Controller as={<IonInput type="email" />}              name="email"              control={control}              onChangeName="onIonChange"            />          </IonItem>          <IonButton expand="block" type="submit" className="ion-margin-top">            Register          </IonButton>        </form>      </IonContent>    </IonPage>);};export default Home;

Это дает нам форму с одним полем ввода для ввода адреса электронной почты. Давайте разберем важные части.

Сначала мы деструктурируем возвращаемое значение хука useForm() из RHF. handleSubmit передает входные значения в функцию-обработчик, которую вы указываете, когда форма проходит валидацию. control — объект, содержащий способы, используемые для регистрации контролируемых компонентов в RHF.

Далее у нас есть стандартный блок элемента формы, но, в отличие от примера для формы входа, мы передаем компонент IonInput компоненту RHF <Controller />, регистрируем событие изменения, устанавливая для свойства <Controller /> onChangeName имя события изменения, а для свойства control — объект управления из вызова useForm().

Пока все отлично, но вы можете обнаружить, что повторяете один и тот же код снова и снова. Вы можете попробовать создать повторно используемый компонент Input, который создает поле ввода ввода с заданными свойствами.

Создайте файл с именем Input.tsx в каталоге src / components и добавьте в него приведенный ниже код:

import React, { FC } from "react";import { IonItem, IonLabel, IonInput } from "@ionic/react";import { Controller, Control } from "react-hook-form";export interface InputProps {  name: string;  control?: Control;  label?: string;  component?: JSX.Element;}const Input: FC<InputProps> =({  name,  control,  component,  label,}) => {  return(    <>      <IonItem>        {label &&(          <IonLabel position="floating">{label}</IonLabel>)}        <Controller as={component?? <IonInput />}          name={name}          control={control}          onChangeName="onIonChange"        />      </IonItem>    </>);};export default Input;

Этот компонент принимает свойство name и необязательный настройка control, свойства component и label выводят поле ввода ввода с использованием ранее представленных компонентов формы Ionic. Это сокращает объем кода, который надо писать при создании полей ввода ввода формы. Вы можете завершить остальную часть формы при помощи этого компонента. Отредактируйте файл Home.tsx, внеся в него следующие изменения:

import { IonContent, IonPage, IonText, IonInput, IonButton, IonCheckbox, IonItem, IonLabel } from "@ionic/react";import React from "react";import "./Home.css";import { useForm } from "react-hook-form";import Input, { InputProps } from "../components/Input";const Home: React.FC =() => {  const { control, handleSubmit } = useForm();    const formFields: InputProps[] = [    {      name: "email",      component: <IonInput type="email" />,      label: "Email",    },    {      name: "fullName",      label: "Full Name",    },    {      name: "password",      component: <IonInput type="password" clearOnEdit={false} />,      label: "Password",    },  ];  const registerUser =(data) => {    console.log("creating a new user account with: ", data);  };  return(    <IonPage>      <IonContent>        <div className="ion-padding">          <IonText color="muted">            <h2>Create Account</h2>          </IonText>          <form onSubmit={handleSubmit(registerUser)}>            {formFields.map((field, index) =>(              <Input {...field} control={control} key={index} />           ))}            <IonItem>              <IonLabel>I agree to the terms of service</IonLabel>              <IonCheckbox slot="start" />            </IonItem>            <IonButton expand="block" type="submit" className="ion-margin-top">              Register            </IonButton>          </form>        </div>      </IonContent>    </IonPage>  );};export default Home;

Сейчас у нас есть массив полей ввода ввода формы ( name — это единственное обязательное свойство), причем каждое поле ввода выводится с использованием компонента Input . Вы можете без проблем пойти ещё дальше и сохранить данные полей ввода в файле JSON, сохраняя код внутри компонентов при помощи форм. На этом этапе созданное приложение (запущенное по адресу http://localhost:8100 при помощи команды ionic serve ) должно выглядеть следующим образом:

Формы и валидация в Ionic ReactСтраница формы регистрации (iOS)

Что насчет валидации полей ввода?

Вы могли заметить, что поля ввода ввода нашей формы ещё не имеют логики валидации. Если бы это было приложение, предназначенное для реального использования, это могло бы привести ко многим нежелательным эффектам, если API не настроен для валидации входящих данных. Кстати, API должен проверять входящие данные.

RHF поставляется с валидацией, которая соответствует стандарту HTML для встроенной валидации форм. Это хорошо подходит для простой валидации, такой как объявление поля ввода обязательным или установка минимальной и максимальной длины поля ввода. Если вы хотели бы использовать сложную логику валидации, я бы рекомендовал использовать Yup . Хотя вы можете легко использовать любую библиотеку проверки схемы объекта, RHF поддерживает Yup, что называется «из коробки».

Выполните приведенную ниже команду, чтобы установить библиотеку (и набор текста):

yarn add yup @types/yup

Далее добавьте это к импорту компонента:

import { object, string } from 'yup';const Home: React.FC = () => { ... }

Далее добавьте следующий код вверху компонента:

const Home: React.FC = () => {  const validationSchema = object().shape({    email: string().required().email(),    fullName: string().required().min(5).max(32),    password: string().required().min(8),  });  // ...}

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

Наконец, обновите хук useForm() , чтобы использовать схему, которую мы определили, установив свойство validationSchema следующим образом:

const { control, handleSubmit } = useForm({  validationSchema,});

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

Сначала обновите компонент Input , чтобы он выглядел следующим образом:

import React, { FC } from "react";import { IonItem, IonLabel, IonInput, IonText } from "@ionic/react";import { Controller, Control, NestDataObject, FieldError } from "react-hook-form";export interface InputProps {  name: string;  control?: Control;  label?: string;  component?: JSX.Element;  errors?: NestDataObject<Record<string, any>, FieldError>;}const Input: FC<InputProps> = ({  name,  control,  component,  label,  errors,}) => {  return (    <>      <IonItem>        {label && <IonLabel position="floating">{label}</IonLabel>}        <Controller as={component ?? <IonInput />}          name={name}          control={control}          onChangeName="onIonChange"        />      </IonItem>      {errors && errors[name] && (        <IonText color="danger" className="ion-padding-start">          <small>{errors[name].message}</small>        </IonText>      )}    </>  );};export default Input;

В данном случае мы обновили компонент, чтобы приобрести дополнительное необязательное свойство, которое будет объектом ошибки из RHF, а также мы отображаем сообщение об ошибке в возвращаемом поле ввода ввода всякий раз, когда возникает ошибка. И последнее: добавьте объект ошибок в деструктурированный объект и обновите компонент в цикле:

const { control, handleSubmit, errors } = useForm({  validationSchema,});  {formFields.map((field, index) => (    <Input {...field} control={control} key={index} errors={errors} />  ))}

Формы и валидация в Ionic ReactФорма регистрации с сообщениями об ошибках (iOS)

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

{  email: string()    .email('Please provide a valid email address')    .required('This is a required field'),}

Улучшение доступности

Компоненты Ionic обычно являются оболочками для соответствующих нативных элементов, что означает, что они принимают большую часть (если не все) существующих атрибутов этого элемента. Вы можете легко улучшить поля ввода ввода и сделать их более доступными для посетителей с ослабленным зрением, установив атрибуты ARIA с соответствующим текстом.

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

import React, { FC } from "react";import { IonItem, IonLabel, IonInput, IonText } from "@ionic/react";import { Controller, Control, NestDataObject, FieldError } from "react-hook-form";export interface InputProps {  name: string;  control?: Control;  label?: string;  component?: JSX.Element;  errors?: NestDataObject<Record<string, any>, FieldError>;}const Input: FC<InputProps> = ({  name,  control,  component,  label,  errors,}) => {  return (    <>      <IonItem>        {label && <IonLabel position="floating">{label}</IonLabel>}        <Controller as={            component ?? (              <IonInput aria-invalid={errors && errors[name] ? "true" : "false"}                aria-describedby={`${name}Error`}              />            )          }          name={name}          control={control}          onChangeName="onIonChange"        />      </IonItem>      {errors && errors[name] && (        <IonText color="danger" className="ion-padding-start">          <small>            <span role="alert" id={`${name}Error`}>              {errors[name].message}            </span>          </small>        </IonText>      )}    </>  );};export default Input;

Компонент по умолчанию, который IonInput мы передаем Controller, сейчас содержит атрибут aria-invalid, указывающий, есть ли в поле ввода ошибка, и атрибут aria-describedby, указывающий на соответствующее сообщение об ошибке. Сообщение об ошибке сейчас заключено в span, для роли которого ARIA установлено значение «error». Сейчас, когда в поле ввода есть ошибка, программа чтения с экрана выделит это поле ввода и зачитает сообщение об ошибке.

Заключение

Поздравляю! Вы узнали, как создавать и выполнять валидацию форм при работе с кроссплатформенными приложениями Ionic. Вы также увидели, как можно сделать поля ввода ввода доступными для посетителей с нарушением зрения. Надеюсь, это руководство предоставит вам прочную базу, которую вы сможете легко использовать при создании форм в собственных приложениях Ionic React. Существуют и иные компоненты для создания форм (такие как select и radios), которые мы не рассмотрели в этом руководстве, но вы можете узнать о них больше в официальной документации.

Ресурсы

  • Документация Ionic Framework
  • React Hook Form
  • Документация Yup
  • Доступность — MDN

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *