React.js’te Form Yönetimi / React-Hook-Form vs. Formik
Form yönetimi, modern web uygulamalarının en temel parçalarından biridir. Kullanıcıdan veri toplamak, bu veriyi doğrulamak ve işlemek için iyi bir form yönetim sistemi kullanmak hayati öneme sahiptir.
Gerek Vanilla olarak gerekse React.js özellinde form yönetimi uygulamak, oldukça yorucu olması ve hataya açık alanlar bırakması yönüyle geliştiricileri 3.parti bir kütüphane kullanımına yönlendirmektedir.
Bu yaklaşımla birlikte; temel olarak gereksinim duyduğum aşağıdaki sıralı maddeleri ne ölçüde yaptıklarına bakarak kütüphane tercihimi neticelendirmeye çalışıyorum.
- Veri yönetimi,erişimi,kullanılabilirliği(dileğim gibi veri ile oynayabiliyor muyum?)
- Eventlerin yönetimi,uygulanabilirliği(onChange, onBlur vd.)
- Form onaylama süreçlerinin yönetilmesi(onSubmit)
- Validasyonların sağlanabilirliği
- Hata mesajları
- Proje gerekliliklerine uygunluk
- Performans
- Öğrenme eğrisi
- Diğer metrikler
React.js’te form yönetimi için popüler iki kütüphane öne çıkmaktadır: Formik ve React-Hook-Form. Bu yazıda, her iki kütüphaneyi tanıtacak, nasıl kullanıldıklarını örneklerle açıklayacak ve avantajları ile dezavantajlarını karşılaştıracağız.
Formik
Formik, React uygulamalarında form yönetimini basitleştiren bir kütüphanedir. Formik, form durumunu ve doğrulamayı yönetmeyi kolaylaştırır, aynı zamanda built-in form bileşenleri kullanımıyla birlikte büyük formlar bile kolayca yönetilebilir hale getirir.
Formik, uzun süre popülerliğini korumuştur.
Bunda en büyük pay kuşkusuz React dizayn paternlerine uyumlu olarak güncel gelişmeleri kütüphane içinde entegre etmesidir.
- <Formik/>, <Form/>, <Field/>, <ErrorMessage/> bileşenleri ile bizleri kod kalabalığından kurtararak React Context’ten güç alarak compund bileşenlerin işlevselliğini kolay bir biçimde kullanmamıza imkan tanır.
- connect(), withFormik() ile HOC’ patternlerinin uygulanması sağlanmıştır.
- Hook’ların React dünyasında çığır açması sonucunda useFormik(), useField() gibi hook’larla geliştiricilerin form yönetiminde de bu yapıları kullanmasına olanaklı kılmıştır.
Örnekler
Formik bileşenlerini kullanarak basit bir form oluşturma örneği:
import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
const SignupForm = () => (
<Formik
initialValues={{ email: '', password: '' }}
validationSchema={Yup.object({
email: Yup.string().email('Invalid email address').required('Required'),
password: Yup.string().min(6, 'Must be at least 6 characters').required('Required'),
})}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
console.log(values);
setSubmitting(false);
}, 400);
}}
>
{({ isSubmitting }) => (
<Form>
<Field type="email" name="email" />
<ErrorMessage name="email" component="div" />
<Field type="password" name="password" />
<ErrorMessage name="password" component="div" />
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</Form>
)}
</Formik>
);
export default SignupForm;
Bu örnekte:
- initialValues: Formun başlangıç değerlerini belirler.
- validationSchema: Yup kütüphanesi kullanılarak form alanlarının doğrulama kuralları tanımlanır.
- onSubmit: Form gönderildiğinde çalışacak fonksiyonu tanımlar.
- Field: Form alanlarını oluşturur.
- ErrorMessage: Hata mesajlarını gösterir.
Şimdi Hook yapısı ile bir örnek oluşturalım.
import React from 'react';
import { useFormik } from 'formik';
import * as Yup from 'yup';
const SignupForm = () => {
const formik = useFormik({
initialValues: {
email: '',
password: '',
},
validationSchema: Yup.object({
email: Yup.string()
.email('Geçersiz email adresi')
.required('Zorunlu Alan'),
password: Yup.string()
.min(6, 'Şifre en az 6 karakter olmalıdır')
.required('Zorunlu Alan'),
}),
onSubmit: (values, { setSubmitting }) => {
setTimeout(() => {
console.log(values);
setSubmitting(false);
}, 400);
},
});
return (
<form onSubmit={formik.handleSubmit}>
<div>
<label htmlFor="email">Email</label>
<input
id="email"
type="email"
{...formik.getFieldProps('email')}
/>
{formik.touched.email && formik.errors.email ? (
<div>{formik.errors.email}</div>
) : null}
</div>
<div>
<label htmlFor="password">Şifre</label>
<input
id="password"
type="password"
{...formik.getFieldProps('password')}
/>
{formik.touched.password && formik.errors.password ? (
<div>{formik.errors.password}</div>
) : null}
</div>
<div>
<button type="submit" disabled={formik.isSubmitting}>
Gönder
</button>
</div>
</form>
);
};
export default SignupForm;
Bu örnekte:
useFormik
hook'u, formun durumunu ve doğrulama kurallarını yönetir.formik.getFieldProps
fonksiyonu, input alanları için gerekli özellikleri sağlar.formik.handleSubmit
fonksiyonu, formun gönderilmesini yönetir.formik.touched
veformik.errors
, alanların dokunulmuş olup olmadığını ve doğrulama hatalarını kontrol etmek için kullanılır.
Avantajlar
- Kolay Doğrulama: Yup gibi doğrulama kütüphaneleriyle entegre çalışması oldukça basittir.
- Gelişmiş Durum Yönetimi: Form durumu, dokunulmuş alanlar ve hata mesajları gibi bilgileri kolayca yönetebilirsiniz.
Dezavantajlar
- Performans: Büyük formlarda performans sorunları yaşanabilir.
- Öğrenme Eğrisi: Başlangıçta biraz karmaşık gelebilir.
React-Hook-Form
React ekosisiteminde hook’ların yükselişi ve topluluk tarafından yüksek bir destek bulması sebebiyle buna uygun kütüphanelerde hızlı kabul oranı sağlamıştır.
Class yapılarında kullanılmaması bir yana tamamen hook paterni ile var olması bile yüksek oranda kullanım oranına erişmesine engel olmamıştır.
React-Hook-Form, React Hook’larını kullanarak form yönetimini sağlayan hafif bir kütüphanedir. Performans ve kullanılabilirlik açısından oldukça verimlidir.
Bileşen state’lerini uncontrolled olarak yönetmesi en öne çıkan özellik olarak gösterilmektedir.
Uncontrolled state yönetimi sayesinde yalnızca değişiklik görülen bileşen alanında re-render olurken diğer form alanları re-render işlemine uğramıyor ve performans kazanımı elde etmiş oluyoruz. Bileşen değerlerini ref bazlı tutması nedeniyle bunu sağladığını da belirtmek isterim.
Bu süreci şu şekilde yorumlayabiliriz esasında; her bir alan için tek tek useState() atamak yerine alanları bir metod içinde tanımlamak(register) yeterli olacaktır.
Ayrıca register edilen alan içinde hazır olarak tanımlanmış validasyon kurallarına da erişme imkanı tanır. Burada hata mesajlarını da ekleyebilirsiniz.
React-Hook-Form Builder ile form oluşturma süreçlerinizi hızlandırabilirsiniz.
<Controller /> bileşeni kullanılarak Material-UI gibi 3.parti UI kütüphaneleri ile de uyumlu çalışabilmektedir. Ayrıca bu bileşenleri controlled olarak state yönetimine elverişli hale getirir.
useFieldArray() Hook’u kullanılarak dinamik form alanlarının yönetilmesi için ek özellikler sağlaması da gelişmiş yetenekleri arasında sayılabilir.
Örnekler
React-Hook-Form kullanarak basit bir form oluşturma örneği:
import React from 'react';
import { useForm } from 'react-hook-form';
const SignupForm = () => {
const { register, handleSubmit, watch, formState: { errors } } = useForm();
const onSubmit = data => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('email', { required: 'Required', pattern: { value: /^\S+@\S+$/i, message: 'Invalid email address' } })} />
{errors.email && <div>{errors.email.message}</div>}
<input {...register('password', { required: 'Required', minLength: { value: 6, message: 'Must be at least 6 characters' } })} />
{errors.password && <div>{errors.password.message}</div>}
<button type="submit">Submit</button>
</form>
);
}
export default SignupForm;
Bu örnekte:
- register: Form alanlarını kaydeder ve doğrulama kurallarını uygular.
- handleSubmit: Form gönderildiğinde çalışacak fonksiyonu tanımlar.
- formState.errors: Doğrulama hatalarını yönetir ve gösterir.
Avantajlar
- Performans: Minimal yeniden render yapar, bu da performansı artırır.
- Kullanım Kolaylığı: Öğrenmesi ve kullanması oldukça kolaydır.
- Düşük Boyut: Daha az yer kaplar, bu da daha hızlı yükleme süreleri sağlar.
Dezavantajlar
- Gelişmiş Özelliklerin Eksikliği: Çok karmaşık formlar için gerekli bazı özellikleri içermeyebilir.
- Daha Az Kaynak: Formik’e kıyasla daha az dokümantasyona sahiptir.
Formik ve React-Hook-Form Karşılaştırması
Formik ve React-Hook-Form arasında seçim yaparken, kullanım amacınız ve projenizin gereksinimleri belirleyici olacaktır. Formik, büyük ve karmaşık formlar için daha uygun olabilirken, React-Hook-Form performans ve kullanım kolaylığı açısından avantaj sağlar. Formik, daha gelişmiş doğrulama ve durum yönetimi sunarken, React-Hook-Form daha hafif ve hızlıdır.
Bağlantıdan aldığım referansta, basit bir form için yukarıda gösterilen mounting süreleri de performans açısından göz önünde bulundurulmalıdır. Daha karmaşık form yapılarında bu süreler kritik öneme sahip olacaktır.
🏆Metrikler anlamında React-Hook-Form açık ara kazanan olarak öne çıkıyor.
Sonuç
Formik ve React-Hook-Form, React uygulamalarında form yönetimini kolaylaştıran iki güçlü araçtır. Hangi kütüphaneyi seçeceğiniz, ihtiyaçlarınıza ve projelerinizin gereksinimlerine bağlı olacaktır. Her iki kütüphane de kendi avantajları ve dezavantajları ile birlikte gelir ve doğru seçimi yapmak, form yönetimi sürecinizi büyük ölçüde iyileştirebilir.
Kaynaklar:
Döküman
Karşılaştırma
- https://damaris-goebel.medium.com/react-hook-form-vs-formik-e58fb31205c5#:~:text=Looking%20at%20npm%20trends%2C%20React,and%20also%20more%20GitHub%20stars.
- https://medium.com/@louis.young0420/react-hook-form-vs-formik-a-friendly-comparison-d2fc0650f1e3
- https://blog.logrocket.com/react-hook-form-vs-formik-comparison/
- https://dev.to/josephmaina/crafting-forms-in-react-vanilla-vs-react-hook-form-vs-formik-43fl
- https://refine.dev/blog/react-hook-form-vs-formik/#how-to-use-formik
- https://www.dhiwise.com/post/choosing-the-right-form-library-formik-vs-react-hook-form
Metrikler
npmjs: https://www.npmjs.com/package/react-hook-form
github: https://github.com/react-hook-form/react-hook-form