İyonik Reaksiyonda Formlar ve Doğrulama
Yayınlanan: 2022-03-10Ionic Framework, HTML, CSS ve JavaScript kullanarak platformlar arası mobil uygulamalar oluşturmaya yönelik bir UI Araç Takımıdır. Ionic 5'in 2020'nin başlarında piyasaya sürülmesi, React geliştiricilerinin favori araçlarını kullanarak kolayca mobil uygulamalar oluşturmasını sağlayan resmi React desteğiyle geldi. Bununla birlikte, formlarla çalışmak için çok fazla destek yoktur ve React ekosisteminde form oluşturmak için mevcut olan mevcut kitaplıkların çoğu, Ionic Framework'ün bileşenleriyle iyi oynamaz.
Bu eğitimde Ionic React'in UI giriş bileşenlerini kullanarak formları nasıl oluşturacağınızı öğreneceksiniz. Ayrıca, form giriş değişikliklerini algılamaya ve doğrulama kurallarına yanıt vermeye yardımcı olması için bir kitaplığın nasıl kullanılacağını öğreneceksiniz. Son olarak, girdilerinizin ARIA niteliklerine yardımcı metinler ekleyerek formlarınızı ekran okuyucular için erişilebilir hale getirmeyi öğreneceksiniz.
Ionic'in Form Bileşenleri
Formlar, günümüzde çoğu web ve mobil uygulamanın önemli bir parçasıdır. İster kullanıcı kaydı ve oturum açma formları aracılığıyla ister uygulamanızın kısıtlı bölümlerine erişim sağlıyor olun, ister kullanıcılarınızdan geri bildirim topluyor olun, uygulamanızın yaşam döngüsünün bir noktasında bir form oluşturmanız gerekir.
Ionic, formlarla çalışmak için önceden oluşturulmuş bileşenler sağlar; bunlardan bazıları IonItem
, IonLabel
, IonInput
, IonCheckbox
ve IonRadio
. Kendimize herhangi bir stil eklemeden standart görünümlü formlar oluşturmak için bu bileşenleri birleştirebiliriz.
Örneğin, aşağıdaki kod:
<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>
Bize şuna benzeyen bir giriş formu verecek:

Kutunun dışında, Ionic'in form bileşenleri iOS veya Android'de harika görünüyor, ancak React ile çalışıyorsanız biraz hantal olabilirler. React ekosistemindeki çoğu araçta olduğu gibi, işlevsellik ve erişilebilirlik söz konusu olduğunda formlarınızı nasıl oluşturmak istediğinize karar vermeniz gerekir - ikisi de tasarım kadar önemlidir.
Halihazırda aralarından seçim yapabileceğiniz çok sayıda React form yardımcısı olmasına rağmen, bunların çoğu Ionic'in form bileşenleriyle çalışmıyor. Bunun ana nedeninin, Ionic'te bir alan değeri değiştiğinde tetiklenen olayın onIonChange
olması ve mevcut form kitaplıklarının çoğunun onChange
dinlemesi olduğundan şüpheleniyorum.

Tepki Kancası Formu: Küçük ve Hızlı Tepki Formları Kitaplığı
Neyse ki, hepsi kıyamet ve kasvetli değil. Geçenlerde, React projelerinde formlarla çalışmak için bir kitaplık olan React Hook Form (RHF) ile karşılaştım. Kontrollü veya kontrolsüz bileşenler ve giriş doğrulaması için destek sağlar ve API kanca tabanlıdır, bu nedenle yalnızca işlevsel bileşenlerle çalışır.
Ionic React geliştiricileri için en çekici özellik - bence - kontrollü bileşenlerle çalışmak için sağladığı sarmalayıcı <Controller />
bileşenidir. Bileşen, ona ilettiğiniz bileşen örneği için change olay adını belirtmek için kullanılabilen bir onChangeName
sahiptir. Bunun İyonik'te formlarla çalışmayı nasıl gerçekten kolaylaştırdığını ilerideki bölümlerde göstereceğim.
Bir Kayıt Formu Oluşturma
Ionic'te bir kayıt formu oluştururken RHF'nin form işlevselliği konusunda bize nasıl yardımcı olduğunu görelim. Ionic CLI'nin en son sürümünü çalıştırıyorsanız (onaylamak için npm i -g @ionic/cli
komutunu çalıştırın), aşağıdaki komutu çalıştırarak React ile yeni bir Ionic uygulaması başlatın:
ionic start myApp blank --type=react
Burada boş bir şablon kullandım. Özellikle bileşenleriniz İşlevsel Bileşenler olarak yazılmışsa, React Hook Form kitaplığını kolaylıkla kullanmak için mevcut formlarınızı yeniden yazabilmelisiniz.
Not: Bu öğreticiye devam etmeden önce ExploreContainer
bileşenini ve Home.tsx'teki içe aktarımını kaldırmalısınız.
Formunuzu kullanmaya başlamak için, projenizin kök dizininde aşağıdaki komutu çalıştırarak React Hook Form paketini kurun:
yarn add react-hook-form
Bu, React Hook Form kitaplığını projenizde kullanılabilir hale getirecektir. Kütüphaneyi kullanarak bir form giriş alanı oluşturalım. Home.tsx dosyasını açın ve içeriğini aşağıdakiyle değiştirin:
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;
Bu size bir e-posta adresi toplamak için tek bir alana sahip bir form verir. Önemli kısımları parçalayalım (kod bloğunda vurgulanmıştır).
İlk olarak, useForm()
kancasının dönüş değerini bozuyoruz. handleSubmit
, form doğrulamayı geçtiğinde, girdinizin değerlerini belirttiğiniz işleyici işlevine iletir. control
, kontrol edilen bileşenleri RHF'ye kaydetmek için kullanılan yöntemleri içeren bir nesnedir.
Ardından, standart bir form öğe bloğumuz var, ancak oturum açma formu örneğinden farklı olarak, IonInput
bileşenini RHF'nin <Controller />
bileşenine iletiriz, <Controller />
'nin onChangeName
prop'unu Ionic'in change olayı olarak ayarlayarak change olayını kaydederiz adını seçin ve useForm()
çağırarak control
nesnesini kontrol nesnesine ayarlayın.
Bu şimdiye kadar iyi, ancak kendinizi neredeyse aynı kodu tekrar tekrar tekrar ederken bulabilirsiniz. Verilen özelliklere sahip bir giriş alanı oluşturan yeniden kullanılabilir bir Input
bileşeni yapmayı deneyebilirsiniz.
src/components dizininde Input.tsx adlı bir dosya oluşturun ve dosyaya aşağıdaki kodu ekleyin:
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;
Bu bileşen bir name
prop ve isteğe bağlı control
, component
ve label
props alır ve daha önce tanıtılan İyonik form bileşenlerini kullanarak bir giriş alanı oluşturur. Bu, form giriş alanları oluştururken yazmanız gereken kod miktarını azaltır. Bu bileşeni kullanarak formunuzun geri kalanını tamamlayabilirsiniz. Home.tsx dosyasını aşağıdaki değişikliklerle düzenleyin:

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;
Şimdiye kadar yaptığınız kurulumla, formunuzun giriş alanlarından oluşan bir diziye sahipsiniz ( name
gerekli olan tek özelliktir), her alan daha önceki Input
bileşeni kullanılarak oluşturulmuştur. Bunu daha da ileri götürebilir ve alan verilerinizi bir JSON dosyasında bulundurabilir, formlarla bileşenlerinizdeki kodu temiz tutabilirsiniz. Bu noktada uygulamanız ( ionic serve
komutuyla https://localhost:8100'de çalışıyor) şöyle görünmelidir:

Alan Doğrulaması Nasıl Olur?
Formumuzun giriş alanlarının henüz doğrulama mantığına sahip olmadığını fark etmişsinizdir. Bu, gerçek dünyada kullanıma yönelik bir uygulamaysa, API'niz gelen verileri doğrulamak üzere ayarlanmadıkça, bu pek çok istenmeyen etkiye yol açabilir. Bu arada, API'niz her zaman gelen verileri doğrulamalıdır.
RHF, yerleşik form doğrulama için HTML standardıyla uyumlu doğrulama ile birlikte gelir. Bu, bir alanı gerekli kılmak veya minimum ve maksimum alan uzunluklarını ayarlamak gibi basit doğrulama için harika çalışır. Karmaşık doğrulama mantığı kullanmak istiyorsanız, Yup kullanmanızı tavsiye ederim. Herhangi bir nesne şeması doğrulama kitaplığını kullanabilirsiniz, ancak RHF kutudan çıktığı gibi Yup'u destekler.
Kitaplığı (ve yazımları) yüklemek için aşağıdaki komutu çalıştırın:
yarn add yup @types/yup
Ardından, bunu bileşeninizin içe aktarmalarına ekleyin:
import { object, string } from 'yup'; const Home: React.FC = () => { ... }
Ardından, bileşeninizin en üstüne aşağıdaki kodu ekleyin:
const Home: React.FC = () => { const validationSchema = object().shape({ email: string().required().email(), fullName: string().required().min(5).max(32), password: string().required().min(8), }); // ... }
Burada bir nesne şeması oluşturduk ve yup
kullanarak her bir özelliğe doğrulama kuralları ekledik. Nesnedeki adlar, formunuzun giriş etiketlerindeki adlarla eşleşmelidir, aksi takdirde kurallarınız tetiklenmez.
Son olarak, validationSchema
özelliğini şu şekilde ayarlayarak tanımladığımız şemayı kullanmak için useForm()
güncelleyin:
const { control, handleSubmit } = useForm({ validationSchema, });
Şimdi, gönder düğmesine tıkladığınızda, handleSubmit
işleyicisi çağrılmaz ve form verileri gönderilmez. Tam olarak istediğimiz şey bu olsa da, kullanıcının neler olduğunu bilmesinin bir yolu yok gibi görünüyor. Bir alan doğru doldurulmadığında metin ipuçlarını göstererek bunu düzeltelim.
İlk olarak, Input
bileşenini aşağıdaki gibi görünecek şekilde güncelleyin:
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;
Burada, bileşenimizi RHF'den gelen hata nesnesi olan ekstra bir isteğe bağlı özellik alacak şekilde güncelledik ve bir hata olduğunda döndürülen giriş alanında bir hata mesajı gösteriyoruz. Son bir şey, destructed nesnenize error nesnesini ekleyin ve döngünüzdeki bileşeni güncelleyin:
const { control, handleSubmit, errors } = useForm({ validationSchema, });
{formFields.map((field, index) => ( <Input {...field} control={control} key={index} errors={errors} /> ))}

Formlarınız artık bir kullanıcı bir şeyi doğru yapmadığında görsel ipuçları sağlıyor. Yup, hata mesajını değiştirmenizi sağlar. Bunu, kullandığınız doğrulama yöntemine bir dize ileterek yapabilirsiniz. E-posta için örnek olarak şunları yapabilirsiniz:
{ email: string() .email('Please provide a valid email address') .required('This is a required field'), }
Erişilebilirliği Geliştirme
Ionic'in bileşenleri genellikle karşılık gelen yerel öğenin üzerindeki sarmalayıcılardır; yani, o öğenin mevcut özelliklerinin çoğunu (hepsini değilse de) kabul ederler. ARIA özniteliklerini ilgili metinle ayarlayarak giriş alanlarınızı iyileştirebilir ve görme engelli kullanıcılar için daha erişilebilir hale getirebilirsiniz.
Örnek kayıt formumuza devam etmek için Input.tsx dosyasını açın ve aşağıdaki değişiklikleri yapın:
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;
Controller
ilettiğimiz varsayılan IonInput
bileşeni, artık alanda bir hata olup olmadığını belirtmek için bir aria-invalid
özniteliği ve ilgili hata mesajını işaret etmek için bir aria-describedby
özniteliği içeriyor. Hata mesajı artık ARIA rolü "hata" olarak ayarlanmış bir span
ile sarılmıştır. Şimdi, alanınızda bir hata olduğunda, bir ekran okuyucu o alanı vurgulayacak ve hata mesajını okuyacaktır.
- GitHub deposunu burada bulacaksınız.
Çözüm
Tebrikler! Ionic kullanarak platformlar arası uygulamalar oluştururken formları nasıl oluşturacağınızı ve doğrulayacağınızı öğrendiniz. Giriş alanlarınızı görme engelli kullanıcılar için erişilebilir hale getirmenin ne kadar kolay olduğunu da gördünüz. Umarım bu eğitim, Ionic React uygulamalarınızda formlar oluştururken kullanabileceğiniz sağlam bir platform sağlar. Form oluşturmak için bu öğreticide keşfetmediğimiz başka bileşenler (seçme ve radyolar gibi) vardır, ancak bunlar hakkında daha fazla bilgiyi resmi belgelerde bulabilir ve okuyabilirsiniz.
Referanslar
- İyonik Çerçeve Belgeleri
- Tepki Kancası Formu
- Evet Dokümanlar
- Phil Haack E-posta Adreslerini Doğruluyor
- MDN Web Dokümanlarında Erişilebilirlik