Урок 07

TextInput

В React Native нет <input>. Вместо него — TextInput.

Базовый

import { TextInput, StyleSheet, View, Text } from 'react-native';
import { useState } from 'react';

export default function Form() {
    const [name, setName] = useState('');

    return (
        <View style={styles.container}>
            <TextInput
                value={name}
                onChangeText={setName}
                placeholder="Введите имя"
                style={styles.input}
            />
            <Text>Привет, {name}</Text>
        </View>
    );
}

Важно: в React Native onChangeText, а не onChange. И значение приходит сразу строкой.

Свойства

<TextInput
    value={text}
    onChangeText={setText}
    placeholder="Email"
    placeholderTextColor="#999"
    keyboardType="email-address"
    autoCapitalize="none"
    autoCorrect={false}
    secureTextEntry           // для пароля
    multiline                 // многострочное
    numberOfLines={4}
    maxLength={100}
    editable={false}
    autoFocus
    returnKeyType="done"
    onSubmitEditing={() => console.log('отправлено')}
/>

keyboardType

  • default
  • email-address
  • numeric
  • phone-pad
  • number-pad
  • decimal-pad
  • url

Клавиатура и скролл

Клавиатура перекрывает экран. Решение — KeyboardAvoidingView:

import { KeyboardAvoidingView, Platform } from 'react-native';

<KeyboardAvoidingView
    behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
    style={{ flex: 1 }}
>
    <TextInput placeholder="Введите текст" />
</KeyboardAvoidingView>

Или ScrollView с keyboardShouldPersistTaps:

<ScrollView keyboardShouldPersistTaps="handled">
    {/* форма */}
</ScrollView>

Dismiss клавиатуры

Нажатие вне поля — скрыть клавиатуру:

import { TouchableWithoutFeedback, Keyboard } from 'react-native';

<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
    <View style={{ flex: 1 }}>
        {/* контент */}
    </View>
</TouchableWithoutFeedback>

Фокус

import { useRef } from 'react';

const inputRef = useRef<TextInput>(null);

<TextInput ref={inputRef} />

inputRef.current?.focus();
inputRef.current?.blur();

Переход между полями:

const emailRef = useRef<TextInput>(null);

<TextInput
    placeholder="Email"
    returnKeyType="next"
    onSubmitEditing={() => passwordRef.current?.focus()}
/>
<TextInput ref={passwordRef} placeholder="Пароль" />

Форма

const [values, setValues] = useState({ email: '', password: '' });

function update(key: keyof typeof values, value: string) {
    setValues((v) => ({ ...v, [key]: value }));
}

<TextInput
    value={values.email}
    onChangeText={(v) => update('email', v)}
    keyboardType="email-address"
    autoCapitalize="none"
/>
<TextInput
    value={values.password}
    onChangeText={(v) => update('password', v)}
    secureTextEntry
/>

Если ты уже знаешь React

В вебе — <input value={x} onChange={e => setX(e.target.value)} />. В React Native — <TextInput value={x} onChangeText={setX} />. Значение приходит сразу, без e.target.value.

Итоги

  • TextInput вместо input
  • onChangeText вместо onChange
  • keyboardType для типа клавиатуры
  • secureTextEntry для паролей
  • KeyboardAvoidingView против перекрытия
  • ref для фокуса