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)Подсветка, тень, underline
focusedЭлемент в фокусе клавиатурыOutline, 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

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

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

js
<Pressable
  onPress={() => console.log('Pressed')}
  onLongPress={() => console.log('Long press')}
  onPressIn={() => console.log('Finger down')}
  onPressOut={() => console.log('Finger up')}
  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 44x44 точки. hitSlop позволяет соблюсти это требование без изменения визуального размера.

hitSlop принимает объект { top, bottom, left, right } или единое число для всех сторон. Значения задаются в логических пикселях (dp/pt). Для иконок 24x24 рекомендуется hitSlop минимум 10-12 с каждой стороны, чтобы достичь 44x44 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 до 44x44 точек без изменения визуального размера, улучшая UX на маленьких элементах
  • API включает onPress, onLongPress, onPressIn, onPressOut с настраиваемой задержкой через delayLongPress
  • android_ripple добавляет Material Design ripple-эффект на Android 5+ с настройкой цвета и формы
  • Миграция с Touchable требует замены автоматических эффектов на явную стилизацию через функцию состояния
  • Animated + Pressable создают плавные анимации нажатия с useNativeDriver для производительности

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

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