A useForm egy fantasztikus hook, amivel űrlapokat lehet ellenőrizni, azaz validálni. A React Hook Form csomagban található.
Sajnos a React Native-al kapcsolatban elég karcsú a példatár a hivatalos dokumentációban is, úgyhogy hoztam egy példát, amiben igyekszem a legtöbb magyarázatot megadni.
Miért jó a React Hook Form?
Azért, mert megakadályozza a komponensek újrarenderelését. Ugyanis általában, amikor egy űrlapot készítünk, aminek van mondjuk egy szöveg mezője, akkor a TextInput komponenst használjuk a szövegbeviteli mezőhöz. Valamint a useState-et ahhoz, hogy a bevitt értéket használni / kezelni is tudjuk. Valahányszor begépelünk valamit a szövegmezőbe, annak meghívódik az onChangeText függvénye, ami kivált egy újra renderelést, vagyis újra építi a DOM-ban a szövegmezőt. Ezzel bár, ha nehezen vagy egyáltalán nem is észrevehető módon, de csökkenti az alkalmazásunk sebességét.
Telepítés
Az első lépés, hogy hozzáadjuk a projektünkhöz a react-hook-form csomagot. Ehhez konzolban ki kell adnunk a következő parancsot:
// yarn
yarn add react-hook-form
// vagy NPM-el
npm install react-hook-form
A példánk működése elméletben
Az egyszerűség kedvéért legyen adott egy szimpla űrlap, amin van egy kor beírására alkalmas szövegmező, ami 18 vagy annál nagyobb két jegyű számot fogad csak el. Valamint egy szín választó, ami egy három elemű rádió gomb csoport, ahol legalább egy opciót ki kell választani.
Lesz egy submit gomb is, amivel az adatokat elküldjük.
Ha minden helyesen ki van töltve, akkor el tudjuk az adatokat küldeni. Ha azonban bármi hiba van az adatok helyességét illetően, akkor hibát jelzünk és nem küldjük el az adatokat.

useForm hook
A useForm hook-ot arra használjuk, hogy visszakapjunk bizonyos dolgokat:
const {
control,
handleSubmit,
formState: { error, isValid },
} = useForm();
React Native esetében ez a control objektum, a handleSubmit függvény és a formState objektum.
- A control objektummal lehet a komponenseket a React Hook Form-ba regisztrálni.
- A handleSubmit függvény kapja meg az űrlap mezők adatait, ha a form validáció sikeres.
- A formState objektum pedig infókat tárol az űrlap állapotáról. Van egy csomó tulajdonsága. Ezek közül a legfontosabb az errors, ami a validáció közben fellépett hibákat adja vissza. Valamint az isValid, aminek értéke true, ha nem volt validációs hiba.
A Controller
Ahhoz, hogy egy normál TextInput (és bármilyen űrlap elem, amit validálni akarunk a React Hook Form-al) alkalmas legyen a validációra, a <Controller /> komponensen belül kell megadni, annak is a render() metódusán belül:
<Controller
control={control}
name="age"
rules={{
required: {
value: true,
message: 'Required',
},
min: {
value: 18,
message: 'Minimum value is 18',
},
}}
render={({
field: { onChange, value, onBlur },
fieldState: { error },
}) => (
<>
<TextInput
keyboardType="number-pad"
maxLength={2}
placeholder="Enter your age here"
value={value}
onBlur={onBlur}
onChangeText={(value) => onChange(value)}
/>
{error && (
<Text style={[styles.errorText, { color: "red" }]}>
{error.message || 'Error'}
</Text>
)}
</>
)}
/>
Hosszúnak néz ki a kód, de egyáltalán nem bonyolult. Nézzük felülről lefelé:
- A control tulajdonságban adjuk meg a useForm hook-ból kivett control objektumot.
- A name az magának a mezőnek a neve.
- A rules objektumban adjuk meg azokat a szabályokat, amiknek a szövegmezőbe bevitt értéknek meg kell felelnie. Azt mondhatjuk, hogy minden egyes szabályt, egy objektummal adhatunk meg. Esetemben van egy required nevű objektum, aminek két további tulajdonsága van. Az egyik a value, aminek a true értékével azt jelezzük, hogy a mező nem maradhat üresen, azaz kötelező kitölteni. A message tulajdonság értékében adjuk meg azt a szöveget, amit akkor kell megjeleníteni, ha a delikvens nem adta meg az értéket.
A rules objektumon belüli másik szabályt leíró objektum, a min. Vagyis mi lehet a mező legkisebb értéke, ha számról van szó. Ezt szintén a value tulajdonságban adtam meg. Itt is van egy message tulajdonság. Ebbe kerül a hiba szövege, ha a szabály nem teljesül. - A következő fontos tulajdonság a render metódus. Ezen belül egy névtelen függvényt hívunk. A függvény paraméterében megadunk egy objektumot. A field tulajdonságban soroljuk fel azokat a módokat, amiket a TextInputhoz használni akarunk. A teljes lista itt van.
A fieldState tulajdonságban vesszük át a hiba objektumot.
A névtelen függvény törzsében jelenítjük meg magát a TextInput-ot. Illetve jelen esetben még megadtam egy Text komponenst is, amiben a hibaüzenetet jelenítem meg. - Maga a TextInput a szokásos tulajdonságokat használja, ami a React Native doksiban is van.
A handleSubmit
Még egy dolog kell az adatok elküldéséhez. Ez pedig egy gomb:
<Pressable onPress={handleSubmit(onSave)}>
<Text style={styles.submitText}>Submit</Text>
</Pressable>
Én most a Pressable komponens segítségével valósítottam meg az elküldés gombot, ami egy linkszerű gomb lett igazából :).
A lényeg az onPress eseményben van, ahol látható, hogy a useForm-ból kiszedett handleSubmit függvénynek adom át az általam írt onSave kezelőt.
Az onSave egy egyszerű kis aszinkron függvény (mert a form validálása aszinkron műveletként lett megírva a tervezői által), ami csak annyit csinál, hogy siker esetén kiírja a konzolba az értékeket. Hiba esetén pedig egy hibát:
const onSave = async (data) => {
try {
console.log('onSave');
console.log(`Age is ${data.age}`);
console.log(`Color is ${data.color}`);
} catch (e) {
console.log(e.message);
}
};
Expo Snack – a működő példa
Maga a példa itt található. Mobilon (Expo Go applikációval) és weben egyaránt kipróbálható közvetlenül a Snack-en belül.
Ha megnézed a kódot, akkor látod, hogy két fajta komponenst használtam. Az egyik az maga a TextInput, ami a react-native csomag része. A másik pedig egy saját komponens, ami a react-native-paper csomag alapján valósít meg egy rádió gomb csoportot. Erről ebben a bejegyzésben olvashatsz.
A lényeg, hogy meg akartam mutatni, hogy a useForm-ot hogyan lehet „gyári” react-native, valamint saját komponens esetén használni.