React — PropTypes ile Tip Kontrolü Yapmak
--
React props (properties), bir component’ten diğerine veri geçirmeye yarar. Bu veriler, string, integer, object ve array gibi temel tiplerden oluşabilir. Eğer herhangi bir state management tool’u kullanmıyorsanız ve uygulamanız içerisinde çok fazla derine inen prop drilling’ler yapıyorsanız prop’larınız componentler arası geçişlerde farkında olmadan değişikliğe uğrayabilir. Dolayısıyla en alt seviyedeki component sizden bir object beklerken arada yaşanan bir değişiklik nedeniyle integer veri gelmiş olabilir. Bu da en alt seviyedeki component’inizde hata oluşma ihtimalini arttırır.
JavaScript weakly-typed bir dildir. Yani karşıt bir örnek vermek gerekirse C++’ta değişken tanımlaması
int a = 12;
şeklinde yapılır. Programınızın çalışma zamanında (run time) a değişkenine bir string değer atamaya çalıştığınız zaman hata alırsınız. Çünkü a değişkeni sadece integer bir değer kabul etmektedir. Bu durum C++’ı strongly typed bir dil yapar.
JavaScript’te ise
let a = 12;
şeklinde bir değişken tanımlaması yapabilirsiniz. Eğer a değerine run time’da bir string ataması yaparsanız JavaScript size herhangi bir error göstermez. Çünkü JavaScript sizi tip konusunda kısıtlamaz. Bunun hızlı development yapabilmeniz açısından faydası olduğu gibi, uygulamanızın değişken tipleri bakımından hataya açık olmasına neden olabilir. Bu sebeple TypeScript ve Flow gibi uygulamalar geliştirilmiştir. Ancak React, TypeScript ve Flow’a ihtiyaç duymayacağınız kendi içerisinde prop’lar için tip validasyonları gerçekleştirebileceğiniz bir mekanizma geliştirmiştir. Fakat diyorsanızki “Benim özgür ruhuma kimse pranga vuramaz!” o halde bir şey diyemeyeceğim.
prop-types Paketinin Kurulumu
NPM kullanıyorsanız bu adresteki paketi aşağıdaki komutla projenize kurun;
npm install --save prop-types
Eğer yarn kullanıyorsanız ise bu adresteki paketi, aşağıdaki komutu kullanarak kurun;
yarn add prop-types
React’te PropTypes Kullanmak
React component’leri propTypes adında özel bir tip kontrolü değerine sahiptir.
import PropTypes from 'prop-types';function CustomComponent(props) {
// ...bla bla bla
}
CustomComponent.propTypes = {
// Prop'larınızın tip kontrolünü ise burada gerçekleştireceksiniz.
}
CustomComponent component’inize bir prop geldiği zaman, propTypes’ın içerisinde gelen değerlerin yanlış bir türde olup olmadığının kontrolü yapılır.
Eğer bir yanlışlık söz konusu ise bu console’da error olarak yazar;
Burada unutmamanız gereken husus, propTypes ile tip kontrolü sadece development ortamında yapılır. Production ortamında performans sebepleriyle tip kontrolü yapmaz.
React PropTypes Validator
React PropTypes bize çok fazla validator ile birlikte geliyor. Validator’dan kastım, CustomComponent.propTypes = {} objesi içerisinde kullanacağımız tip kontrolü tanımlamaları. Aşağıda bazı temel validator’ları göreceksiniz;
PropTypes.any
: Prop herhangi bir tipte olabilir.PropTypes.bool
: Prop boolean olmak zorundaPropTypes.number
: Prop number olmak zorundaPropTypes.string
: Prop string olmak zorundaPropTypes.func
: Prop function olmak zorundaPropTypes.array
: Prop array olmak zorundaPropTypes.object
: Prop object olmak zorundaPropTypes.symbol
: Prop symbol olmak zorunda
Bunların örnek kullanımını aşağıda görebilirsiniz. propTypes objesinin key’leri oluşturduğunuz componen’teki prop’lar ile aynı isimde olmak zorundadır. Aksi halde hata alabilirsiniz.
import PropTypes from 'prop-types';function CustomComponent({anyProp, booleanProp, numberProp, stringProp}) {
// ...bla bla bla
}
CustomComponent.propTypes = {
anyProp: PropTypes.any,
booleanProp: PropTypes.bool,
numberProp: PropTypes.number,
stringProp: PropTypes.string,
}
Eğer component’inizde olup propTypes içerisinde olmayan bir prop’unuz varsa bunun kontrolü gerçekleştirilmez. Console’da da bununla ilgili herhangi bir hata görmezsiniz.
Render’lanabilir Tipler
Component’inizin prop’larına yukarıdaki tipler haricinde render edilebilir değerler de geçebilirsiniz. Örneğin bir prop’a başka bir component’i verebilirsiniz
<Custom someProp = {<OtherComponent/>} />
Bu durumda nasıl veri tipi kontrolü gerçekleştirmeniz gerekir? Bunun içinde PropTypes paketi aşağıdaki validator’leri bize sunuyor;
PropTypes.node
: Prop , React tarafından render edilen herhangi bir şey olabilir. (number, string, element, veya array)PropTypes.element
: Prop bir React elementi olmak zorundadır.
CustomComponent.propTypes = {
nodeProp: PropTypes.node,
elementProp: PropTypes.element
}
Instance Tipleri
Bazı durumlarda prop’un tipinin bir JavaScript class’ı türünde olmasını isteyebilirsiniz o zaman PropTypes.instanceOf validator’unu kıllanmalısınız.
CustomComponent.propTypes = {
personProp: PropTypes.instanceOf(Animal)
}
Çoklu tipler
Prop’larınız sadece tek bir tür veri almayabilir. Örneğin; oluşturduğunuz component’in bir prop’u string tipinde bir veri alabilir fakat bu prop’a <AnotherComponent> adında farklı bir component’te gönderme ihtimaliniz de olabilir. Dolayısıyla bu prop’a farklı türlerde değer gelebileceği için bunları da PropTypes.oneOf ve PropTypes.oneOfType validator’leri ile handle etmiş olacağız.
PropTypes.oneOf
: Bu validator teknik olarak enum gibi çalışır. Prop’ları belli başlı değerler ile kısıtlamanıza yarar.
CustomComponent.propTypes = {
enumProp: PropTypes.oneOf(["banana", 0, true, false,]),
}
PropTypes.oneOfType
: Bir prop’a birden fazla validator atamanıza yarar.
CustomComponent.propTypes = {
unionProp: PropTypes.oneOfType([
PropType.bool,
PropType.number,
PropType.string,
PropType.instanceOf(Person)
])
}
Collection Tipleri
PropTypes.array validator’ü ile prop’a bir array gelip gelmediğini kontrol edebiliyorduk, diyelim ki bir dropdown menu butonumuz var bu butona basıldığında aşağısında menu item’leri gözükmesini istiyoruz dolayısıyla şöyle bir component hayal edelim;
<DropDownButton menuItems = {
[
<Item>Banana</Item>,
<Item>Apple</Item>,
<Item>Watermelon</Item>,
]
}/>
Burada menuItems dizisinin içerisine yanlışlıkla Item’den farklı bir bir component gelirse bunu nasıl PropTypes ile yakalayacağız? Burada imdadımıza Proptypes.arrayOf koşuyor.
PropTypes.arrayOf
validator’ü prop’a gelen array’in içerisindeki tipleri kontrol etmemize yarar.
DropDownButton.propTypes = {
menuItems: PropTypes.arrayOf(
PropTypes.instanceOf(Item)
),
}
Sadece Item gelmeyecekse farklı tipler de gelecekse o halde PropTypes’ı şu şekilde oluşturmalıyız.
DropDownButton.propTypes = {
multipleArrayProp: PropTypes.arrayOf(
PropTypes.oneOfType([
PropTypes.instanceOf(Item),
PropType.string
])
)
}
PropTypes.shape
Prop’ların bir diğer genel kullanımı ise API’dan JSON türünde gelen verileri diğer component’ler ile paylaşmaktır. Elimize gelen bu JSON objesi, component’ler arası geçişlerde değişikliğe uğrayabilir dolayısıyla objenin elemenlarını daha detaylı valide etmek isteyebiliriz. Bu durumda PropTypes.shape validator’ünü kullanmalıyız.
Component.propTypes = {
profileProp: PropTypes.shape({
id: PropTypes.number,
fullname: PropTypes.string,
gender: PropTypes.oneOf(['M', 'F']),
birthdate: PropTypes.instanceOf(Date),
isAuthor: PropTypes.bool
})
}
PropTypes.exact
Daha katı bir object validasyonu yapmak istiyorsak o halde PropTypes.exact validator’ünü kullanabiliriz.
CustomComponent.propTypes = {
subjectScoreProp: PropTypes.exact({
subject: PropTypes.oneOf(['Maths', 'Arts', 'Science']),
score: PropTypes.number
})
}
Required (Gerekli) Tipler
Buraya kadar sadece component’e bir prop verilmişse bunun kontrolünü yapıyorduk, verilmemişse de bizim için çok önemli değildi. Fakat bir component’iniz herhangi bir prop’unun kesinlikle bir değer alması gerekebilir. Dolayısıyla bu prop’a bir değer gelmesi gerekirken o değerin gelip gelmediğini nasıl kontrol edeceğiz?
Component.propTypes = {
requiredAnyProp: PropTypes.any.isRequired,
requiredFunctionProp: PropTypes.func.isRequired,
requiredSingleElementProp: PropTypes.element.isRequired,
requiredPersonProp: PropTypes.instanceOf(Person).isRequired,
requiredEnumProp: PropTypes.oneOf(['Read', 'Write']).isRequired,
requiredShapeObjectProp: PropTypes.shape({
title: PropTypes.string.isRequired,
date: PropTypes.instanceOf(Date).isRequired,
isRecent: PropTypes.bool
}).isRequired
}
Bu yazıda TypeScript veya Flow gibi üçüncü bir katmana ihtiyaç duymadan PropTypes paketini kullanarak React’te tip validasyonlarını nasıl yapabileceğimizi öğrenmiş olduk. Bu paketle birlikte daha güvenli bir ürün geliştirmesi yapabilirsiniz :)
Bu yazıda kullanılan içeriklerin büyük bir bölümü, örneklerin bazıları ve ekran görüntüleri Glad Chinda’nın https://blog.logrocket.com/validating-react-component-props-with-prop-types-ef14b29963fc/ adlı makalesinden alınmıştır.