React Native course ยท Module 5: Forms

Picker, Switch and Other Controls

3 min read ยท
In this lesson5

React Native offers various form controls.

Switch

import { Switch } from 'react-native';

function SettingsForm() {
  const [notifications, setNotifications] = useState(true);
  const [darkMode, setDarkMode] = useState(false);

  return (
    <View>
      <View style={styles.row}>
        <Text>Notifications</Text>
        <Switch
          value={notifications}
          onValueChange={setNotifications}
          trackColor={{ false: '#767577', true: '#81b0ff' }}
          thumbColor={notifications ? '#1a5276' : '#f4f3f4'}
          ios_backgroundColor="#3e3e3e"
        />
      </View>

      <View style={styles.row}>
        <Text>Dark Mode</Text>
        <Switch
          value={darkMode}
          onValueChange={setDarkMode}
        />
      </View>
    </View>
  );
}

Picker (expo)

npx expo install @react-native-picker/picker
import { Picker } from '@react-native-picker/picker';

function CountryPicker() {
  const [country, setCountry] = useState('us');

  return (
    <View style={styles.pickerContainer}>
      <Text style={styles.label}>Country:</Text>
      <Picker
        selectedValue={country}
        onValueChange={(value) => setCountry(value)}
        style={styles.picker}
      >
        <Picker.Item label="United States" value="us" />
        <Picker.Item label="Germany" value="de" />
        <Picker.Item label="France" value="fr" />
        <Picker.Item label="Italy" value="it" />
      </Picker>
    </View>
  );
}

Custom Checkbox

import { Pressable, View, Text } from 'react-native';
import { Ionicons } from '@expo/vector-icons';

interface CheckboxProps {
  checked: boolean;
  onChange: (checked: boolean) => void;
  label: string;
}

function Checkbox({ checked, onChange, label }: CheckboxProps) {
  return (
    <Pressable
      style={styles.checkboxContainer}
      onPress={() => onChange(!checked)}
    >
      <View style={[styles.checkbox, checked && styles.checkboxChecked]}>
        {checked && <Ionicons name="checkmark" size={16} color="#fff" />}
      </View>
      <Text style={styles.checkboxLabel}>{label}</Text>
    </Pressable>
  );
}

const styles = StyleSheet.create({
  checkboxContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    marginVertical: 8,
  },
  checkbox: {
    width: 24,
    height: 24,
    borderWidth: 2,
    borderColor: '#1a5276',
    borderRadius: 4,
    justifyContent: 'center',
    alignItems: 'center',
  },
  checkboxChecked: {
    backgroundColor: '#1a5276',
  },
  checkboxLabel: {
    marginLeft: 10,
    fontSize: 16,
  },
});

Radio Buttons

interface RadioOption {
  value: string;
  label: string;
}

interface RadioGroupProps {
  options: RadioOption[];
  value: string;
  onChange: (value: string) => void;
}

function RadioGroup({ options, value, onChange }: RadioGroupProps) {
  return (
    <View>
      {options.map((option) => (
        <Pressable
          key={option.value}
          style={styles.radioContainer}
          onPress={() => onChange(option.value)}
        >
          <View style={styles.radio}>
            {value === option.value && <View style={styles.radioSelected} />}
          </View>
          <Text style={styles.radioLabel}>{option.label}</Text>
        </Pressable>
      ))}
    </View>
  );
}

// Usage
function PaymentForm() {
  const [paymentMethod, setPaymentMethod] = useState('card');

  return (
    <RadioGroup
      options={[
        { value: 'card', label: 'Credit card' },
        { value: 'paypal', label: 'PayPal' },
        { value: 'transfer', label: 'Bank transfer' },
      ]}
      value={paymentMethod}
      onChange={setPaymentMethod}
    />
  );
}

Date/Time Picker

npx expo install @react-native-community/datetimepicker
import DateTimePicker from '@react-native-community/datetimepicker';

function DatePicker() {
  const [date, setDate] = useState(new Date());
  const [show, setShow] = useState(false);

  const onChange = (event: any, selectedDate?: Date) => {
    setShow(Platform.OS === 'ios');
    if (selectedDate) {
      setDate(selectedDate);
    }
  };

  return (
    <View>
      <Pressable onPress={() => setShow(true)} style={styles.dateButton}>
        <Text>{date.toLocaleDateString('en-US')}</Text>
      </Pressable>

      {show && (
        <DateTimePicker
          value={date}
          mode="date"
          display="default"
          onChange={onChange}
          locale="en-US"
        />
      )}
    </View>
  );
}

Diverse controls allow you to create intuitive forms!

Code for this lesson: App.tsx
import React, { useState } from 'react';
import { View, Text, Pressable, StyleSheet } from 'react-native';
import { Ionicons } from '@expo/vector-icons';

interface CheckboxProps {
  checked: boolean;
  onChange: (checked: boolean) => void;
  label: string;
}

function Checkbox({ checked, onChange, label }: CheckboxProps) {
  return (
    <Pressable
      style={styles.checkboxContainer}
      // TODO: in onPress call onChange(!checked) to toggle the selection
    >
      <View style={[styles.checkbox, checked && styles.checkboxChecked]}>
        {/* TODO: if checked === true, render <Ionicons name="checkmark" size={16} color="#fff" /> */}
      </View>
      <Text style={styles.checkboxLabel}>{label}</Text>
    </Pressable>
  );
}

export default function App() {
  const [accepted, setAccepted] = useState(false);

  return (
    <View style={styles.container}>
      <Checkbox
        checked={accepted}
        onChange={setAccepted}
        label="I accept the Atlantis terms"
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    justifyContent: 'center',
    backgroundColor: '#1a5276',
  },
  checkboxContainer: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  checkbox: {
    width: 24,
    height: 24,
    borderWidth: 2,
    borderColor: '#aed6f1',
    borderRadius: 4,
    justifyContent: 'center',
    alignItems: 'center',
  },
  checkboxChecked: {
    backgroundColor: '#2980b9',
    borderColor: '#2980b9',
  },
  checkboxLabel: {
    marginLeft: 10,
    fontSize: 16,
    color: '#fff',
  },
});

Docs entries used in this lesson

Spotted a mistake in this lesson?

Check yourself

Answer the questions from this lesson. Pick an answer to see right away whether it is correct.

  1. 1. Which component is used for on/off toggles?

  2. 2. Which library is used for date selection in Expo?

Hands-on tasks in the game

  • Horizontal ordering

    Arrange a basic Picker:

  • Code editor

    Complete the Checkbox code with Pressable and an icon.

Useful articles