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, където ефектът на натискане е твърдо определен (промяна на прозрачността), Pressable предоставя функция, която получава текущото състояние. Разработчикът сам решава как да реагира визуално на допир: да промени цвета, мащаба, сянката или комбинация от ефекти. Това предоставя пълен контрол над UX.

Състояния на Pressable: pressed, hovered, focused

Pressable определя три състояния на взаимодействие: pressed (пръст на екрана), hovered (курсор над елемента на Web/TV), focused (елемент във фокус на клавиатурата). Всяко състояние активира съответното обратно извикване и се предава на функцията за стилове и на функцията за рендиране на деца.

СъстояниеУсловиеТипична реакция
pressedПръст на екрана или клик натиснатПромяна на прозрачността, мащаба, цвета на фона
hoveredКурсор над елемента (Web, TV)Осветляване, сянка, подчертаване
focusedЕлемент във фокус на клавиатуратаКонтур, рамка, промяна на цвета

Важно: 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 позволява създаване на персонализирани анимации.

Допълнителни props: 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 — prop на Pressable, който разширява областта на допир извън видимите граници на компонента. Критичен е за малки елементи: икони, квадратчета за избор, радио бутони. Apple HIG препоръчва минимален размер на touch target от 44x44 точки. hitSlop позволява изпълняването на това изискване без промяна на визуалния размер.

hitSlop приема обект { top, bottom, left, right } или едно число за всички страни. Стойностите се посочват в логически пиксели (dp/pt). За икони 24x24 се препоръчва hitSlop от поне 10-12 от всяка страна за постигане на touch target от 44x44.

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 + прозрачност в 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 и прозрачност, нативният драйвер се поддържа на всички платформи.

Често задавани въпроси

Мога ли да използвам Pressable вместо TouchableOpacity без промяна на кода?

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

Как да направя ripple ефект като в Material Design?

Използвайте prop android_ripple с обект { color, borderless }. Цветът на ripple се посочва в rgba формат. За кръгли бутони използвайте borderless: true. Ripple работи само на Android 5+. На iOS използвайте персонализирана анимация.

Защо onPress не работи при бързо превъртане?

Pressable има вградена защита срещу случайни натискания при превъртане. Ако потребителят превърта списък, onPress не се вика. Този поведение може да се настрои чрез pressRetentionOffset и delayPressIn.

Как да проследя дълго натискане с Pressable?

Използвайте prop 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 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също