React Native Cheatsheet
Forms and Input
Use this React Native reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
TextInput Reference
import { TextInput, View, Text, StyleSheet } from 'react-native'; <TextInput value={text} onChangeText={(value) => setText(value)} onFocus={() => setFocused(true)} onBlur={() => setFocused(false)} onSubmitEditing={() => handleSubmit()} // Enter key pressed onEndEditing={() => validate()} // Editing ended (blur or submit) onKeyPress={({ nativeEvent }) => { if (nativeEvent.key === 'Backspace') handleDelete(); }} placeholder="Enter text" placeholderTextColor="#999" defaultValue="initial" // uncontrolled style={[styles.input, focused && styles.inputFocused]} />
TextInput Props
| Prop | Type | Notes |
|---|---|---|
value | string | Controlled value |
defaultValue | string | Uncontrolled initial value |
onChangeText | (text: string) => void | New value each keystroke |
onChange | ({ nativeEvent }) => void | Raw event with text |
multiline | boolean | Multi-line textarea |
numberOfLines | number | Android: min lines for multiline |
maxLength | number | Character limit |
editable | boolean | Disable editing |
selectTextOnFocus | boolean | Select all on tap |
selection | { start, end } | Programmatic selection |
caretHidden | boolean | Hide cursor |
textAlignVertical | 'auto' | 'top' | 'bottom' | 'center' | Android only |
scrollEnabled | boolean | iOS multiline only |
Keyboard Types
keyboardType | Use case |
|---|---|
'default' | General text |
'email-address' | |
'numeric' | Numbers only |
'number-pad' | Number pad (no symbols) |
'decimal-pad' | Decimals |
'phone-pad' | Phone number |
'url' | URLs |
'ascii-capable' | ASCII only |
'visible-password' | Password visible (Android) |
Return Key Types
returnKeyType | Label shown |
|---|---|
'done' | Done |
'go' | Go |
'next' | Next |
'search' | Search |
'send' | Send |
'none' | No label (Android) |
Auto-correction & Capitalization
| Prop | Values |
|---|---|
autoCapitalize | 'none' | 'sentences' | 'words' | 'characters' |
autoCorrect | boolean |
autoComplete | 'off' | 'username' | 'password' | 'email' | 'name' | etc. |
spellCheck | boolean (iOS) |
textContentType | iOS autofill hint (see below) |
iOS textContentType values (autofill)
'none' | 'URL' | 'addressCity' | 'creditCardNumber' | 'emailAddress' | 'familyName' | 'fullStreetAddress' | 'givenName' | 'jobTitle' | 'location' | 'name' | 'newPassword' | 'oneTimeCode' | 'organizationName' | 'password' | 'postalCode' | 'streetAddressLine1' | 'telephoneNumber' | 'username'
Controlled Input with Validation
function EmailInput() { const [email, setEmail] = useState(''); const [error, setError] = useState(''); const validate = (value: string) => { if (!value.includes('@')) setError('Invalid email'); else setError(''); }; return ( <View> <TextInput value={email} onChangeText={(v) => { setEmail(v); validate(v); }} onBlur={() => validate(email)} keyboardType="email-address" autoCapitalize="none" autoCorrect={false} textContentType="emailAddress" style={[styles.input, error ? styles.inputError : null]} /> {error ? <Text style={styles.error}>{error}</Text> : null} </View> ); } const styles = StyleSheet.create({ input: { borderWidth: 1, borderColor: '#ccc', borderRadius: 8, padding: 12 }, inputError: { borderColor: '#e00' }, error: { color: '#e00', fontSize: 12, marginTop: 4 }, });
Multi-field Form with Focus Chain
function LoginForm() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const passwordRef = useRef<TextInput>(null); return ( <View> <TextInput value={email} onChangeText={setEmail} placeholder="Email" keyboardType="email-address" autoCapitalize="none" returnKeyType="next" onSubmitEditing={() => passwordRef.current?.focus()} blurOnSubmit={false} // Don't dismiss keyboard between fields style={styles.input} /> <TextInput ref={passwordRef} value={password} onChangeText={setPassword} placeholder="Password" secureTextEntry textContentType="password" returnKeyType="done" onSubmitEditing={handleLogin} style={styles.input} /> <Pressable onPress={handleLogin} style={styles.button}> <Text style={styles.buttonText}>Login</Text> </Pressable> </View> ); }
React Hook Form (community — recommended)
npm install react-hook-form
import { useForm, Controller } from 'react-hook-form'; type FormData = { email: string; password: string; }; function LoginForm() { const { control, handleSubmit, formState: { errors, isSubmitting } } = useForm<FormData>({ defaultValues: { email: '', password: '' }, }); const onSubmit = async (data: FormData) => { await login(data.email, data.password); }; return ( <View> <Controller control={control} name="email" rules={{ required: 'Email is required', pattern: { value: /\S+@\S+\.\S+/, message: 'Invalid email' }, }} render={({ field: { onChange, onBlur, value } }) => ( <TextInput value={value} onChangeText={onChange} onBlur={onBlur} keyboardType="email-address" autoCapitalize="none" placeholder="Email" style={[styles.input, errors.email && styles.inputError]} /> )} /> {errors.email && <Text style={styles.error}>{errors.email.message}</Text>} <Controller control={control} name="password" rules={{ required: 'Password is required', minLength: { value: 8, message: 'Min 8 characters' } }} render={({ field: { onChange, onBlur, value } }) => ( <TextInput value={value} onChangeText={onChange} onBlur={onBlur} secureTextEntry placeholder="Password" style={[styles.input, errors.password && styles.inputError]} /> )} /> {errors.password && <Text style={styles.error}>{errors.password.message}</Text>} <Pressable onPress={handleSubmit(onSubmit)} disabled={isSubmitting}> <Text>{isSubmitting ? 'Logging in…' : 'Login'}</Text> </Pressable> </View> ); }
Keyboard Handling
import { Keyboard, KeyboardAvoidingView, Platform, TouchableWithoutFeedback } from 'react-native'; // Dismiss keyboard on tap outside <TouchableWithoutFeedback onPress={Keyboard.dismiss}> <View style={{ flex: 1 }}> <TextInput ... /> </View> </TouchableWithoutFeedback> // Push content above keyboard <KeyboardAvoidingView style={{ flex: 1 }} behavior={Platform.OS === 'ios' ? 'padding' : 'height'} keyboardVerticalOffset={Platform.OS === 'ios' ? 90 : 0} > <ScrollView> {/* form fields */} </ScrollView> </KeyboardAvoidingView> // Programmatic keyboard control Keyboard.dismiss(); // Listen for keyboard events Keyboard.addListener('keyboardDidShow', (event) => { console.log(event.endCoordinates.height); // keyboard height });
Picker / Select
npm install @react-native-picker/picker
import { Picker } from '@react-native-picker/picker'; const [selected, setSelected] = useState('java'); <Picker selectedValue={selected} onValueChange={(value) => setSelected(value)} style={{ height: 50 }} mode="dropdown" // Android: 'dropdown' | 'dialog' > <Picker.Item label="JavaScript" value="js" /> <Picker.Item label="TypeScript" value="ts" /> <Picker.Item label="Java" value="java" /> </Picker>
DateTimePicker
npm install @react-native-community/datetimepicker
import DateTimePicker from '@react-native-community/datetimepicker'; const [date, setDate] = useState(new Date()); const [show, setShow] = useState(false); {show && ( <DateTimePicker value={date} mode="date" // 'date' | 'time' | 'datetime' display="default" // 'default' | 'spinner' | 'calendar' | 'clock' onChange={(event, selectedDate) => { setShow(Platform.OS === 'ios'); // stay visible on iOS if (selectedDate) setDate(selectedDate); }} minimumDate={new Date(2000, 0, 1)} maximumDate={new Date()} /> )} <Pressable onPress={() => setShow(true)}> <Text>{date.toLocaleDateString()}</Text> </Pressable>
Switch / Checkbox / Radio
import { Switch } from 'react-native'; // Toggle const [isEnabled, setIsEnabled] = useState(false); <Switch value={isEnabled} onValueChange={setIsEnabled} trackColor={{ false: '#ccc', true: '#4CAF50' }} thumbColor={isEnabled ? '#fff' : '#f4f3f4'} /> // Custom Checkbox pattern function Checkbox({ checked, onToggle, label }) { return ( <Pressable onPress={onToggle} style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }} accessibilityRole="checkbox" accessibilityState={{ checked }} > <View style={[styles.box, checked && styles.boxChecked]}> {checked && <Text style={{ color: '#fff' }}>✓</Text>} </View> <Text>{label}</Text> </Pressable> ); }
Slider
npm install @react-native-community/slider
import Slider from '@react-native-community/slider'; const [value, setValue] = useState(50); <Slider value={value} onValueChange={setValue} onSlidingComplete={(val) => console.log('Final:', val)} minimumValue={0} maximumValue={100} step={1} minimumTrackTintColor="#007AFF" maximumTrackTintColor="#ccc" thumbTintColor="#007AFF" />