Pressable — co to jest, obsługa dotknięć w React Native

Autor: IT Sectr Opublikowano: 2026-07-06 Czas czytania: 10 min

Pressable — nowoczesny komponent React Native do obsługi dotknięć, zastępujący przestarzałe TouchableHighlight, TouchableOpacity i TouchableWithoutFeedback. Pressable udostępnia jednolity API z wykrywaniem stanów pressed, hovered i focused. Komponent pojawił się w React Native 0.63 i jest zalecany przez Meta dla wszystkich nowych projektów. Więcej o komponencie przeczytasz w dokumentacji Meta.

Najważniejsze

  • Pressable — uniwersalny komponent do obsługi dotknięć z obsługą stanów pressed, hovered, focused
  • API zawiera callbacki onPress, onLongPress, onPressIn, onPressOut i funkcję stylizacji opartą na stanie
  • hitSlop rozszerza obszar dotyku poza widoczne granice komponentu dla poprawy UX
  • Zastąpienie Touchable — Pressable ujednolica API wszystkich komponentów Touchable w jeden elastyczny interfejs
  • Dostępność — komponent obsługuje role ARIA i automatycznie przetwarza VoiceOver i TalkBack

Czym jest Pressable?

Pressable — komponent React Native udostępniający jednolity interfejs do obsługi wszystkich typów dotknięć. W przeciwieństwie do trzech różnych komponentów Touchable (TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback), Pressable zastępuje je jednym z elastycznym systemem stanów i stylizacji.

Komponent został wprowadzony w React Native 0.63 (wrzesień 2020). Według danych Meta (2026), 70% nowych projektów na React Native używa Pressable zamiast komponentów Touchable. Pressable rozwiązuje kluczowy problem Touchable — rozproszone API i konieczność przełączania się między komponentami dla różnych efektów.

Filozofia Pressable

W przeciwieństwie do TouchableOpacity, gdzie efekt dotknięcia jest sztywno określony (zmiana przezroczystości), Pressable udostępnia funkcję odbierającą bieżący stan. Deweloper sam decyduje, jak wizualnie reagować na dotknięcie: zmienić kolor, skalę, cień lub kombinację efektów. Daje to pełną kontrolę nad UX.

Stany Pressable: pressed, hovered, focused

Pressable definiuje trzy stany interakcji: pressed (palec na ekranie), hovered (kursor nad elementem na Web/TV), focused (element w fokusie klawiatury). Każdy stan aktywuje odpowiedni callback i jest przekazywany do funkcji stylów oraz funkcji renderującej dzieci.

StanWarunekTypowa reakcja
pressedPalec na ekranie lub kliknięcie przytrzymaneZmiana przezroczystości, skali, koloru tła
hoveredKursor nad elementem (Web, TV)Podświetlenie, cień, podkreślenie
focusedElement w fokusie klawiaturyKonturka, obramowanie, zmiana koloru

Ważne: hovered i focused działają tylko na platformach z obsługą wskaźnika (Web, Android TV, Apple TV). Na urządzeniach mobilnych dostępny jest tylko stan pressed. W przypadku aplikacji wieloplatformowych projektuj reakcje wizualne, mając to ograniczenie na uwadze.

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 i callbacki Pressable

API Pressable zawiera cztery główne callbacki: onPress (pełne naciśnięcie z puszczeniem), onLongPress (długie naciśnięcie), onPressIn (początek dotknięcia) i onPressOut (koniec dotknięcia). Kombinacja onPressIn i onPressOut pozwala tworzyć niestandardowe animacje.

Dodatkowe props: delayLongPress (opóźnienie długiego naciśnięcia, domyślnie 500 ms), pressRetentionOffset (obszar, poza którym naciśnięcie jest anulowane), android_ripple (efekt ripple na Androidzie). Ważne: Ripple działa tylko na Android 5+.

js
<Pressable
  onPress={() => console.log('Naciśnięto')}
  onLongPress={() => console.log('Długie naciśnięcie')}
  onPressIn={() => console.log('Palec w dół')}
  onPressOut={() => console.log('Palec w górę')}
  delayLongPress={300}
  android_ripple={{ color: 'rgba(0,0,0,0.1)', borderless: false }}
  style={styles.button}>
  <Text>Press me</Text>
</Pressable>

onPress jest wywoływany tylko wtedy, gdy palec zostanie podniesiony wewnątrz obszaru komponentu (z uwzględnieniem pressRetentionOffset). Jeśli użytkownik przesunie palec poza granice, onPress nie zadziała, co zapobiega fałszywym naciśnięciom. onPressOut jest wywoływany w każdym przypadku przy puszczeniu.

hitSlop: rozszerzenie obszaru dotyku

hitSlop — props Pressable rozszerzający obszar dotyku poza widoczne granice komponentu. Jest to krytyczne dla małych elementów: ikon, checkboxów, przycisków radio. Apple HIG zaleca minimalny rozmiar touch target 44x44 punkty. hitSlop pozwala spełnić to wymaganie bez zmiany rozmiaru wizualnego.

hitSlop przyjmuje obiekt { top, bottom, left, right } lub pojedynczą liczbę dla wszystkich stron. Wartości podawane są w logicznych pikselach (dp/pt). Dla ikon 24x24 zalecany hitSlop to minimum 10-12 z każdej strony, aby osiągnąć 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 — odwrotność hitSlop: określa obszar, na który użytkownik może wyjść poza granice komponentu bez anulowania naciśnięcia. Domyślnie jest równy hitSlop. Jeśli potrzebujesz, aby naciśnięcie było zachowane przy wyjściu poza granice, zwiększ pressRetentionOffset.

Pressable vs Touchable: kiedy przejść

Pressable vs Touchable — kluczowe pytanie przy wyborze komponentu do obsługi dotknięć. TouchableOpacity, TouchableHighlight i TouchableWithoutFeedback to przestarzałe komponenty, które nie zostaną usunięte, ale nie otrzymują nowych funkcji. Meta zaleca Pressable dla nowych projektów.

Główne zalety Pressable: jednolity API dla wszystkich typów efektów, dostęp do stanu pressed dla niestandardowej stylizacji, obsługa stanów hovered/focused, hitSlop i pressRetentionOffset, callback onLongPress bez dodatkowej konfiguracji. TouchableOpacity nadaje się tylko do prostej zmiany przezroczystości.

ScenariuszTouchablePressable
Proste naciśnięcieTouchableOpacityPressable + przezroczystość w style
Podświetlenie tłaTouchableHighlightPressable + backgroundColor
Bez efektu wizualnegoTouchableWithoutFeedbackPressable z pustym style
Długie naciśnięcieonLongPress na dowolnym TouchableonLongPress na Pressable
Niestandardowa animacjaAnimated + onPressIn/OutPressable + useAnimatedStyle
Ripple na AndroidzieTouchableNativeFeedbackPressable + android_ripple

Przykłady użycia Pressable

Pressable pozwala tworzyć złożone elementy interaktywne z minimalną ilością kodu. Poniżej — przykład animowanego przycisku ze zmianą skali przy naciśnięciu i efektem ripple na Androidzie. Taki przycisk zastępuje kombinację 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>
  );
};

Ważne: używaj useNativeDriver: true dla animacji w Pressable. Przenosi to animację do natywnego wątku, zapobiegając spadkom klatek przy szybkich naciśnięciach. Dla transform i przezroczystości natywny sterownik jest obsługiwany na wszystkich platformach.

Często zadawane pytania

Czy mogę używać Pressable zamiast TouchableOpacity bez zmiany kodu?

Nie, Pressable ma inne API. TouchableOpacity automatycznie stosuje przezroczystość przy naciśnięciu. Pressable wymaga jawnego określenia stylu przez funkcję stanu. Zastąpienie jest trywialne: przekaż style={({ pressed }) => [{ opacity: pressed ? 0.5 : 1 }]}.

Jak zrobić efekt ripple jak w Material Design?

Użyj propsa android_ripple z obiektem { color, borderless }. Kolor ripple podaje się w formacie rgba. Dla okrągłych przycisków użyj borderless: true. Ripple działa tylko na Android 5+. Na iOS używaj niestandardowej animacji.

Dlaczego onPress nie działa przy szybkim przewijaniu?

Pressable ma wbudowaną ochronę przed przypadkowymi naciśnięciami podczas przewijania. Jeśli użytkownik przewija listę, onPress nie jest wywoływane. To zachowanie można skonfigurować przez pressRetentionOffset i delayPressIn.

Jak śledzić długie naciśnięcie za pomocą Pressable?

Użyj propsa onLongPress — wbudowana obsługa długiego naciśnięcia. Opóźnienie konfiguruje się przez delayLongPress (domyślnie 500 ms). Dla menu kontekstowych i drag-and-drop połącz onLongPress z onPressIn.

Czy Pressable obsługuje nawigację klawiaturową?

Tak, Pressable obsługuje stan focused do nawigacji klawiaturowej na Android TV, Apple TV i Web. Użyj stylizacji przez { focused } do wyświetlania fokusu. Na urządzeniach mobilnych stan focused nie ma zastosowania.

Podsumowanie

  • Pressable — uniwersalny komponent React Native do obsługi dotknięć, zastępujący TouchableOpacity, TouchableHighlight i TouchableWithoutFeedback
  • Stany pressed, hovered, focused są przekazywane do funkcji stylów, umożliwiając dostosowanie reakcji dla każdego scenariusza
  • hitSlop rozszerza touch target do 44x44 punktów bez zmiany rozmiaru wizualnego, poprawiając UX na małych elementach
  • API zawiera onPress, onLongPress, onPressIn, onPressOut z konfigurowalnym opóźnieniem przez delayLongPress
  • android_ripple dodaje efekt ripple Material Design na Android 5+ z konfiguracją koloru i kształtu
  • Migracja z Touchable wymaga zastąpienia automatycznych efektów jawną stylizacją przez funkcję stanu
  • Animated + Pressable tworzą płynne animacje naciśnięcia z useNativeDriver dla wydajności

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również