Pressable — що це, обробка натискань у React Native

Автор: IT Sectr Опубліковано: 2026-07-06 Час читання: 10 хв

Pressable — сучасний компонент React Native для обробки дотиків, який замінює застарілі TouchableHighlight, TouchableOpacity та TouchableWithoutFeedback. Pressable надає єдиний API з виявленням станів pressed, hovered та focused. Компонент з’явився в React Native 0.63 і рекомендується Meta для всіх нових проєктів. Докладніше про компонент читайте в документації Meta.

Головне

  • Pressable — універсальний компонент для обробки дотиків із підтримкою станів pressed, hovered, focused
  • API включає колбеки onPress, onLongPress, onPressIn, onPressOut та функцію стилізації на основі стану
  • hitSlop розширює область дотику за межі видимих меж компонента для поліпшення UX
  • Заміна Touchable — Pressable уніфікує API всіх Touchable-компонентів в один гнучкий інтерфейс
  • Доступність — компонент підтримує ARIA-ролі та автоматично обробляє VoiceOver і TalkBack

Що таке Pressable?

Pressable — компонент React Native, що надає єдиний інтерфейс для обробки всіх типів дотиків. На відміну від трьох різних Touchable-компонентів (TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback), Pressable замінює їх одним із гнучкою системою станів та стилізації.

Компонент було представлено в React Native 0.63 (вересень 2020). За даними Meta (2026), 70% нових проєктів на React Native використовують Pressable замість Touchable-компонентів. Pressable вирішує ключову проблему Touchable — розрізнений API та необхідність перемикатися між компонентами для різних ефектів.

Філософія Pressable

На відміну від TouchableOpacity, де ефект натискання жорстко заданий (зміна opacity), Pressable надає функцію, яка отримує поточний стан. Розробник сам вирішує, як візуально реагувати на натискання: змінити колір, масштаб, тінь або комбінацію ефектів. Це дає повний контроль над UX.

Стани Pressable: pressed, hovered, focused

Pressable визначає три стани взаємодії: pressed (палець на екрані), hovered (курсор над елементом на Web/TV), focused (елемент у фокусі клавіатури). Кожен стан активує відповідний колбек і передається в функцію стилів та дочірню render-функцію.

СтанУмоваТипова реакція
pressedПалець на екрані або клік затиснутийЗміна opacity, scale, кольору фону
hoveredКурсор над елементом (Web, TV)Підсвітка, тінь, підкреслення
focusedЕлемент у фокусі клавіатуриОбведення, border, зміна кольору

Важливо: hovered та focused працюють лише на платформах із підтримкою вказівника (Web, Android TV, Apple TV). На мобільних пристроях доступний лише pressed. Для крос-платформових застосунків проєктуйте візуальні реакції з огляду на це обмеження.

js
<Pressable
  style={({ pressed }) => [
    styles.button,
    pressed && styles.buttonPressed,
  ]}
  onPress={handlePress}>
  {({ pressed }) => (
    <Text style={pressed ? styles.textPressed : styles.text}>
      {pressed ? 'Release' : 'Press'}
    </Text>
  )}
</Pressable>

API та колбеки Pressable

API Pressable включає чотири основні колбеки: onPress (повне натискання з відпусканням), onLongPress (довге натискання), onPressIn (початок дотику) та onPressOut (закінчення дотику). Комбінація onPressIn та onPressOut дозволяє створювати кастомні анімації.

Додаткові пропси: delayLongPress (затримка довгого натискання, за замовчуванням 500 ms), pressRetentionOffset (область, за межами якої натискання скасовується), android_ripple (ефект ripple на Android). Важливо: Ripple працює лише на Android 5+.

js
<Pressable
  onPress={() => console.log('Натиснуто')}
  onLongPress={() => console.log('Довге натискання')}
  onPressIn={() => console.log('Палець вниз')}
  onPressOut={() => console.log('Палець вгору')}
  delayLongPress={300}
  android_ripple={{ color: 'rgba(0,0,0,0.1)', borderless: false }}
  style={styles.button}>
  <Text>Press me</Text>
</Pressable>

onPress викликається лише якщо палець піднято всередині області компонента (з урахуванням pressRetentionOffset). Якщо користувач відводить палець за межі, onPress не спрацьовує, що запобігає хибним натисканням. onPressOut викликається в будь-якому разі при відпусканні.

hitSlop: розширення області дотику

hitSlop — пропс Pressable, що розширює область дотику за межі видимих меж компонента. Це критично для маленьких елементів: іконок, чекбоксів, радіо-кнопок. Apple HIG рекомендує мінімальний розмір touch target 44×44 точки. hitSlop дозволяє дотриматися цієї вимоги без зміни візуального розміру.

hitSlop приймає об’єкт { top, bottom, left, right } або єдине число для всіх сторін. Значення задаються в логічних пікселях (dp/pt). Для іконок 24×44 рекомендується hitSlop мінімум 10–12 з кожного боку, щоб досягти 44×44 touch target.

js
<Pressable
  hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
  onPress={handleIconPress}
  style={styles.iconButton}>
  <Icon name="star" size={24} />
</Pressable>

pressRetentionOffset — зворотній hitSlop: визначає область, на яку користувач може вийти за межі компонента, не скасовуючи натискання. За замовчуванням дорівнює hitSlop. Якщо потрібно, щоб натискання зберігалося при виході за межі, збільште pressRetentionOffset.

Pressable vs Touchable: коли переходити

Pressable vs Touchable — ключове питання при виборі компонента для обробки дотиків. TouchableOpacity, TouchableHighlight та TouchableWithoutFeedback — застарілі компоненти, які не будуть видалені, але не отримують нових можливостей. Meta рекомендує Pressable для нових проєктів.

Основні переваги Pressable: єдиний API для всіх типів ефектів, доступ до стану pressed для кастомної стилізації, підтримка станів hovered/focused, hitSlop та pressRetentionOffset, колбек onLongPress без додаткових налаштувань. TouchableOpacity підходить лише для простої зміни прозорості.

СценарійTouchablePressable
Просте натисканняTouchableOpacityPressable + opacity в style
Підсвітка фонуTouchableHighlightPressable + backgroundColor
Без візуального ефектуTouchableWithoutFeedbackPressable із порожнім style
Довге натисканняonLongPress на будь-якому TouchableonLongPress на Pressable
Кастомна анімаціяAnimated + onPressIn/OutPressable + useAnimatedStyle
Ripple на AndroidTouchableNativeFeedbackPressable + android_ripple

Приклади використання Pressable

Pressable дозволяє створювати складні інтерактивні елементи з мінімальним кодом. Нижче — приклад анімованої кнопки зі зміною масштабу при натисканні та ripple-ефектом на Android. Така кнопка замінює комбінацію TouchableOpacity + Animated.

js
const AnimatedButton = ({ title, onPress }) => {
  const scale = React.useRef(new Animated.Value(1)).current;

  const handlePressIn = () => {
    Animated.spring(scale, {
      toValue: 0.96,
      useNativeDriver: true,
    }).start();
  };

  const handlePressOut = () => {
    Animated.spring(scale, {
      toValue: 1,
      friction: 3,
      useNativeDriver: true,
    }).start();
  };

  return (
    <Pressable
      onPress={onPress}
      onPressIn={handlePressIn}
      onPressOut={handlePressOut}
      android_ripple={{ color: 'rgba(255,255,255,0.3)' }}
      style={styles.button}>
      <AnimatedView style={[styles.inner, { transform: [{ scale }] }]}>
        <Text style={styles.text}>{title}</Text>
      </AnimatedView>
    </Pressable>
  );
};

Важливо: використовуйте useNativeDriver: true для анімацій у Pressable. Це переносить анімацію в нативний потік, запобігаючи просіданню кадрів при швидких натисканнях. Для transform та opacity нативний драйвер підтримується на всіх платформах.

Часті запитання

Чи можна використовувати Pressable замість TouchableOpacity без зміни коду?

Ні, Pressable має інший API. TouchableOpacity автоматично застосовує opacity при натисканні. Pressable вимагає явного вказання стилю через функцію стану. Заміна тривіальна: передайте style={({ pressed }) => [{ opacity: pressed ? 0.5 : 1 }]}.

Як зробити ripple ефект як у Material Design?

Використовуйте пропс android_ripple з об’єктом { color, borderless }. Колір ripple задається у форматі rgba. Для круглих кнопок використовуйте borderless: true. Ripple працює лише на Android 5+. На iOS використовуйте кастомну анімацію.

Чому onPress не спрацьовує при швидкому скролі?

Pressable має вбудований захист від випадкових натискань при скролі. Якщо користувач скролить список, onPress не викликається. Цю поведінку можна налаштувати через pressRetentionOffset та delayPressIn.

Як відстежити довге натискання з Pressable?

Використовуйте пропс onLongPress — вбудована підтримка довгого натискання. Затримка налаштовується через delayLongPress (за замовчуванням 500 ms). Для контекстних меню та drag-and-drop комбінуйте onLongPress з onPressIn.

Чи підтримує Pressable клавіатурну навігацію?

Так, Pressable підтримує стан focused для клавіатурної навігації на Android TV, Apple TV та Web. Використовуйте стилізацію через { focused } для відображення фокусу. На мобільних пристроях стан focused не актуальний.

Підсумки

  • Pressable — універсальний компонент React Native для обробки дотиків, що замінює TouchableOpacity, TouchableHighlight та TouchableWithoutFeedback
  • Стани pressed, hovered, focused передаються в функцію стилів, дозволяючи кастомізувати реакцію під кожен сценарій
  • hitSlop розширює touch target до 44×44 точок без зміни візуального розміру, покращуючи UX на маленьких елементах
  • API включає onPress, onLongPress, onPressIn, onPressOut з налаштовуваною затримкою через delayLongPress
  • android_ripple додає Material Design ripple-ефект на Android 5+ з налаштуванням кольору та форми
  • Міграція з Touchable вимагає заміни автоматичних ефектів на явну стилізацію через функцію стану
  • Animated + Pressable створюють плавні анімації натискання з useNativeDriver для продуктивності

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також