Kurs React Native · Moduł 5: Formularze

Picker, Switch i inne kontrolki

3 min czytania ·
W tej lekcji5

React Native oferuje różne kontrolki formularzy.

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>Powiadomienia</Text>
        <Switch
          value={notifications}
          onValueChange={setNotifications}
          trackColor={{ false: '#767577', true: '#81b0ff' }}
          thumbColor={notifications ? '#1a5276' : '#f4f3f4'}
          ios_backgroundColor="#3e3e3e"
        />
      </View>

      <View style={styles.row}>
        <Text>Tryb ciemny</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('pl');

  return (
    <View style={styles.pickerContainer}>
      <Text style={styles.label}>Kraj:</Text>
      <Picker
        selectedValue={country}
        onValueChange={(value) => setCountry(value)}
        style={styles.picker}
      >
        <Picker.Item label="Polska" value="pl" />
        <Picker.Item label="Niemcy" value="de" />
        <Picker.Item label="Francja" value="fr" />
        <Picker.Item label="Włochy" 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>
  );
}

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

  return (
    <RadioGroup
      options={[
        { value: 'card', label: 'Karta kredytowa' },
        { value: 'blik', label: 'BLIK' },
        { value: 'transfer', label: 'Przelew' },
      ]}
      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('pl-PL')}</Text>
      </Pressable>

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

Różnorodne kontrolki pozwalają tworzyć intuicyjne formularze!

Kod do tej lekcji: 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: w onPress wywołaj onChange(!checked), aby przełączyć zaznaczenie
    >
      <View style={[styles.checkbox, checked && styles.checkboxChecked]}>
        {/* TODO: jeśli checked === true, wyświetl <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="Akceptuję regulamin Atlantydy"
      />
    </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',
  },
});

Hasła z dokumentacji w tej lekcji

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Który komponent służy do przełączników on/off?

  2. 2. Jaka biblioteka służy do wyboru daty w Expo?

Zadania praktyczne w grze

  • Układanie w poziomie

    Ułóż podstawowy Picker:

  • Edytor kodu

    Uzupełnij kod Checkbox z Pressable i ikoną.

Przydatne artykuły