Input komponenta
React Native TextInput komponenta
Za input polja koristi se TextInput koji obezbedjuje React Native.
Tako da prvo što treba da uradimo jeste da importujemo
import { TextInput } from 'react-native';
Ubacimo ga u jednu od CardSection komponenti unutar naše LoginForm komponente i za početak odmah upišimo random visinu i širinu jer je podrazumevana veličina i širina TextInput
kao kada su i slike u pitanju jednaka nuli.
<CardSection>
<TextInput style={{ height: 20, width: 100 }} />
</CardSection>
Posle reload-a simulatora videćete da je jedna od CardSection komponenti dobila odredjenu visinu i ako kliknete na sam početak te komponente pojaviće se tekst kursor i moći ćete da pišete.
Sledeći korak je da omogućimo našoj aplikaciji da može da koristi vrednost koja se upiše u ovo input polje. Način na koji to postiže je interesantan, koristićemo state
komponente. Prvo inicijalizujemo state objekat koji ima email
koji je prazan string (jer će prvi input predstavljati mesto za upis email korisnika)
state = { email: '' };
Zatim dodajemo onChangeText
property TextInput-u kome se prosledjuje funckija koja uzima vrednost upisanu unutar input-a i postavlja unutar state-a komponente pomoću funkcije setState
. I još definišemo property value
TextInput-a da bude jednak email
property-ju state-a komponente.
<CardSection>
<TextInput
value={ this.state.email }
onChangeText={ email => this.setState({ email: email }) }
style={{ height: 20, width: 100 }} />
</CardSection>
Šta se ovde zapravo dešava je sledeće
- Izrenderuje se TextInput
- Korisnik krene da upisuje tekst
- Kako korisnik upisuje tekst poziva se
onChangeText
event koji predstavlja funkciju koja pozivasetState
metodu - Poziva se
setState
i postavlja nova vrednost zaemail
i ono sto je JAKO BITNO, komponenta se rerender-uje. (Podsetnik, svakim pozivanjemsetState
komponenta se rerender-uje). - I tada
value
TextInput komponente dobija vrednostthis.state.email
Ovim, možda malo komplikovanim načinom, dobijamo ono što smo želeli, a to je da je komponenta "svesna" vrednosti koja se upisuje unutar input-a, time što tu vrednost dodeljujemo state-u komponente, i moguće je koristiti dalje. Nama je na primer potrebno da znamo koji mail i šifru je korisnik upisa kako bi mogli da završimo proces autentifikacije.
Reusable Input komponenta
Pošto smo prešli suštinu načina rada TextInput-a i onoga što želimo da postignemo, napravimo jednu Input komponentu koju ćemo moći da koristimo više puta i na više mesta.
Unutar components direktorijuma napravićemo fajl Input.js koji će izgledati ovako:
import React from 'react';
import { TextInput, View, Text } from 'react-native';
const Input = ({ label, value, onChangeText, placeholder }) => {
return (
<View>
<Text>{ label }</Text>
<TextInput
autoCapitalize='none'
placeholder={ placeholder }
autoCorrect={ false }
value={ value }
onChangeText={ onChangeText }
style={{ height: 20, width: 100 }}
/>
</View>
);
};
export default Input;
I iskoristiti ga u našoj formi : (LoginForm.js)
import React, { Component } from 'react';
import { TextInput } from 'react-native';
import Button from './Button';
import Card from './Card';
import CardSection from './CardSection';
import Input from './Input';
class LoginForm extends Component {
state = { email: '' };
render() {
return (
<Card>
<CardSection>
<Input
placeholder='[email protected]'
label= 'Email'
value={ this.state.email }
onChangeText={ email => this.setState({ email: email }) } />
</CardSection>
<CardSection />
<CardSection>
<Button text='Log in' />
</CardSection>
</Card>
);
}
}
export default LoginForm;
U ova dva bloka koda smo uradili sledeće:
Prvo smo napravili Input komponentu koja kao parametre prima label
, value
, placeholder
i onChangeText
funkciju od svoje parent komponente i koristi ih na odgovarajućim mestima. Stastoji se od <View> komponente koja unutar sebe sadrzi <Text> komponentu koja će predstavljati label unutar input polja i <TextInput> komponente koja je identična onome što smo pisali pre u LoginForm komponenti. Samo vrednosti value
i onChangeText
parametara dobija od parent komponente. (LoginForm). Dodali smo i autoCorrect
property i dodeli mu false
vrednost kako sistem ne bi nudio autokorekciju jer generalno email-ovi mogu biti jako čudnih vrednosti kao i autoCapitalize
sa vrednošću none
kako bi isključili samostalno povećavanje prvog slova u input polju.
I drugo je LoginForm komponenta gde smo samo importovali našu Input komponentu i u render metodi umesto <TextInput> je iskoristili (<Input>), dodali smo label
i placeholder
parametare koji će se proslediti kao i value
koji će sada prosledjivati this.state.email
i onChangeText
koji će prosledjivati funkciju setState
.
I ono što nam je ostalo jeste stilizovanje komponente. Na dnu Input komponente dodaćemo styles
objekat
const styles = {
inputStyle: {
color: '#000',
paddingRight: 5,
paddingLeft: 5,
fontSize: 18,
lineHeight: 23,
flex: 2,
},
labelStyle: {
fontSize: 18,
paddingLeft: 20,
flex: 1,
},
containerStyle: {
height: 40,
flex: 1,
flexDirection: 'row',
alignItems: 'center',
}
};
I dodeliti ih odgovarajućim komponentama
const Input = ({ label, value, onChangeText, placeholder }) => {
const { inputStyle, labelStyle, containerStyle } = styles;
return (
<View style={ containerStyle}>
<Text style={ labelStyle}>{ label }</Text>
<TextInput
autoCapitalize='none'
placeholder={ placeholder }
autoCorrect={ false }
value={ value }
onChangeText={ onChangeText }
style={ inputStyle }
/>
</View>
);
};
Jedni što bih objasnio kod pisanja ovog stila je flex
property.
Kao što vidite <Text> i <TextInput> su "rodjaci" (siblings) elementi, tj nalaze se zajedno unutar jednog "roditelj" (parent) elementa u ovom slučaju <View>. Kako smo i jednom i drugom dodelili property flex
i to vrednosti 1 i 2, ukupan zbir toga je 3, što znači da će <Text> ili ti element sa labelStyle
koji ima flex
vrednost 1 zauzimati celokupne 1/3 širine dok će <TextInput> sa vrednošću 2 zauzimati 2/3. <View> elementu je dodeljen flex: 1
, ali kako on nema siblings elemente on će sam zauzeti celu širinu.
I sada kada odradite reload strane možete videti uobičajno input polje sa label-om i placeholder-om koji nestaje kada se kline i počne sa kucanjem.
Password input
Sada nam je još potreban input polje za šifru. U narednoj <CardSection> komponenti možemo iskoristi ponovo našu <Input> komponentu
<CardSection>
<Input
secureTextEntry={ true }
placeholder= 'password'
label= 'Password'
value={ this.state.password }
onChangeText={ password => this.setState({ password: password }) } />
</CardSection>
Kao što vidite value
sada ima vrednost this.state.password
, i to se isto menja u onChangeText
metodi. Jedina razlika sa input poljem za email je u secureTextEntry
. Ono služi kako bi se sakrila šifra pri kucanju, to jest da se umesto karaktera šifre prikazuju zvezdice/tačkice.
Sada je još samo potrebno da učinimo da naša Input komponenta postane svesna secureTextEntry
property-ja. Zato je potrebno da je uvedemo kao props i zatim je iskoristimo unutar <TextInput> elementa.
const Input = ({ label, value, onChangeText, placeholder, secureTextEntry }) => {
const { inputStyle, labelStyle, containerStyle } = styles;
return (
<View style={ containerStyle}>
<Text style={ labelStyle }>{ label }</Text>
<TextInput
autoCapitalize='none'
secureTextEntry={ secureTextEntry }
placeholder={ placeholder }
autoCorrect={ false }
value={ value }
onChangeText={ onChangeText }
style={ inputStyle }
/>
</View>
);
};
I sada kada reload-ujete svoj simulator imate spremnu formu za Log in.
Sledeći korak je korišćenje Firebase-a za potrebe autentifikacije.