Pressable — apa itu, penanganan sentuhan di React Native

Penulis: IT Sectr Diterbitkan: 2026-07-06 Waktu membaca: 10 mnt

Pressable — komponen React Native modern untuk menangani sentuhan, yang menggantikan TouchableHighlight, TouchableOpacity, dan TouchableWithoutFeedback yang sudah usang. Pressable menyediakan API terpadu dengan deteksi status pressed, hovered, dan focused. Komponen ini muncul di React Native 0.63 dan direkomendasikan oleh Meta untuk semua proyek baru. Baca lebih lanjut tentang komponen ini di dokumentasi Meta.

Utama

  • Pressable — komponen universal untuk penanganan sentuhan dengan dukungan status pressed, hovered, focused
  • API mencakup callback onPress, onLongPress, onPressIn, onPressOut dan fungsi styling berbasis status
  • hitSlop memperluas area sentuhan melampaui batas visual komponen untuk meningkatkan UX
  • Penggantian Touchable — Pressable menyatukan API semua komponen Touchable ke dalam satu antarmuka yang fleksibel
  • Aksesibilitas — komponen mendukung peran ARIA dan secara otomatis menangani VoiceOver dan TalkBack

Apa itu Pressable?

Pressable — komponen React Native yang menyediakan antarmuka terpadu untuk menangani semua jenis sentuhan. Tidak seperti tiga komponen Touchable yang berbeda (TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback), Pressable menggantikan semuanya dengan satu komponen yang memiliki sistem status dan styling yang fleksibel.

Komponen ini diperkenalkan di React Native 0.63 (September 2020). Menurut data Meta (2026), 70% proyek baru di React Native menggunakan Pressable sebagai pengganti komponen Touchable. Pressable memecahkan masalah utama Touchable — API yang terfragmentasi dan kebutuhan untuk beralih antar komponen untuk efek yang berbeda.

Filosofi Pressable

Tidak seperti TouchableOpacity di mana efek sentuhan ditentukan secara kaku (perubahan opacity), Pressable menyediakan fungsi yang menerima status saat ini. Pengembang sendiri yang memutuskan bagaimana merespons secara visual terhadap sentuhan: mengubah warna, skala, bayangan, atau kombinasi efek. Ini memberikan kontrol penuh atas UX.

Status Pressable: pressed, hovered, focused

Pressable mendefinisikan tiga status interaksi: pressed (jari di layar), hovered (kursor di atas elemen di Web/TV), focused (elemen dalam fokus keyboard). Setiap status mengaktifkan callback yang sesuai dan diteruskan ke fungsi gaya dan fungsi render anak.

StatusKondisiReaksi tipikal
pressedJari di layar atau klik ditekanPerubahan opacity, skala, warna latar
hoveredKursor di atas elemen (Web, TV)Penyorotan, bayangan, garis bawah
focusedElemen dalam fokus keyboardGaris luar, batas, perubahan warna

Penting: hovered dan focused hanya berfungsi di platform dengan dukungan penunjuk (Web, Android TV, Apple TV). Di perangkat seluler, hanya pressed yang tersedia. Untuk aplikasi lintas platform, desain reaksi visual dengan mempertimbangkan batasan ini.

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 dan callback Pressable

API Pressable mencakup empat callback utama: onPress (tekan penuh dengan lepas), onLongPress (tekan lama), onPressIn (mulai sentuhan), dan onPressOut (akhir sentuhan). Kombinasi onPressIn dan onPressOut memungkinkan pembuatan animasi kustom.

Props tambahan: delayLongPress (penundaan tekan lama, default 500 md), pressRetentionOffset (area di luar mana tekanan dibatalkan), android_ripple (efek ripple di Android). Penting: Ripple hanya berfungsi di Android 5+.

js
<Pressable
  onPress={() => console.log('Ditekan')}
  onLongPress={() => console.log('Tekanan lama')}
  onPressIn={() => console.log('Jari ke bawah')}
  onPressOut={() => console.log('Jari ke atas')}
  delayLongPress={300}
  android_ripple={{ color: 'rgba(0,0,0,0.1)', borderless: false }}
  style={styles.button}>
  <Text>Press me</Text>
</Pressable>

onPress hanya dipanggil ketika jari diangkat di dalam area komponen (dengan mempertimbangkan pressRetentionOffset). Jika pengguna menggerakkan jari ke luar batas, onPress tidak akan terpicu, mencegah sentuhan palsu. onPressOut dipanggil dalam kasus apapun saat dilepaskan.

hitSlop: memperluas area sentuhan

hitSlop — prop Pressable yang memperluas area sentuhan melampaui batas visual komponen. Ini sangat penting untuk elemen kecil: ikon, kotak centang, tombol radio. Apple HIG merekomendasikan ukuran target sentuhan minimal 44x44 titik. hitSlop memungkinkan memenuhi persyaratan ini tanpa mengubah ukuran visual.

hitSlop menerima objek { top, bottom, left, right } atau satu angka untuk semua sisi. Nilai ditentukan dalam piksel logis (dp/pt). Untuk ikon 24x24, hitSlop minimal 10-12 di setiap sisi direkomendasikan untuk mencapai target sentuhan 44x44.

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

pressRetentionOffset — kebalikan dari hitSlop: menentukan area di mana pengguna dapat melampaui batas komponen tanpa membatalkan tekanan. Secara default sama dengan hitSlop. Jika Anda ingin tekanan tetap dipertahankan saat melampaui batas, tingkatkan pressRetentionOffset.

Pressable vs Touchable: kapan beralih

Pressable vs Touchable — pertanyaan kunci saat memilih komponen untuk penanganan sentuhan. TouchableOpacity, TouchableHighlight, dan TouchableWithoutFeedback adalah komponen usang yang tidak akan dihapus, tetapi tidak mendapatkan fitur baru. Meta merekomendasikan Pressable untuk proyek baru.

Keunggulan utama Pressable: API terpadu untuk semua jenis efek, akses ke status pressed untuk styling kustom, dukungan status hovered/focused, hitSlop dan pressRetentionOffset, callback onLongPress tanpa konfigurasi tambahan. TouchableOpacity hanya cocok untuk perubahan opacity sederhana.

SkenarioTouchablePressable
Tekanan sederhanaTouchableOpacityPressable + opacity di style
Penyorotan latarTouchableHighlightPressable + backgroundColor
Tanpa efek visualTouchableWithoutFeedbackPressable dengan style kosong
Tekanan lamaonLongPress pada Touchable mana punonLongPress pada Pressable
Animasi kustomAnimated + onPressIn/OutPressable + useAnimatedStyle
Ripple di AndroidTouchableNativeFeedbackPressable + android_ripple

Contoh penggunaan Pressable

Pressable memungkinkan pembuatan elemen interaktif kompleks dengan kode minimal. Di bawah ini — contoh tombol animasi dengan perubahan skala saat ditekan dan efek ripple di Android. Tombol semacam itu menggantikan kombinasi 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>
  );
};

Penting: gunakan useNativeDriver: true untuk animasi di Pressable. Ini memindahkan animasi ke thread native, mencegah penurunan frame saat tekanan cepat. Untuk transform dan opacity, driver native didukung di semua platform.

Pertanyaan yang sering diajukan

Bisakah saya menggunakan Pressable sebagai pengganti TouchableOpacity tanpa mengubah kode?

Tidak, Pressable memiliki API yang berbeda. TouchableOpacity secara otomatis menerapkan opacity saat ditekan. Pressable memerlukan penentuan gaya secara eksplisit melalui fungsi status. Penggantiannya sederhana: berikan style={({ pressed }) => [{ opacity: pressed ? 0.5 : 1 }]}.

Bagaimana cara membuat efek ripple seperti di Material Design?

Gunakan prop android_ripple dengan objek { color, borderless }. Warna ripple ditentukan dalam format rgba. Untuk tombol bundar gunakan borderless: true. Ripple hanya berfungsi di Android 5+. Di iOS gunakan animasi kustom.

Mengapa onPress tidak berfungsi saat scrolling cepat?

Pressable memiliki perlindungan bawaan terhadap sentuhan tidak sengaja saat scrolling. Jika pengguna menggulir daftar, onPress tidak dipanggil. Perilaku ini dapat dikonfigurasi melalui pressRetentionOffset dan delayPressIn.

Bagaimana cara melacak tekanan lama dengan Pressable?

Gunakan prop onLongPress — dukungan bawaan untuk tekanan lama. Penundaan dikonfigurasi melalui delayLongPress (default 500 md). Untuk menu konteks dan drag-and-drop, gabungkan onLongPress dengan onPressIn.

Apakah Pressable mendukung navigasi keyboard?

Ya, Pressable mendukung status focused untuk navigasi keyboard di Android TV, Apple TV, dan Web. Gunakan styling melalui { focused } untuk menampilkan fokus. Di perangkat seluler, status focused tidak relevan.

Kesimpulan

  • Pressable — komponen universal React Native untuk penanganan sentuhan, menggantikan TouchableOpacity, TouchableHighlight, dan TouchableWithoutFeedback
  • Status pressed, hovered, focused diteruskan ke fungsi gaya, memungkinkan penyesuaian reaksi untuk setiap skenario
  • hitSlop memperluas target sentuhan hingga 44x44 titik tanpa mengubah ukuran visual, meningkatkan UX pada elemen kecil
  • API mencakup onPress, onLongPress, onPressIn, onPressOut dengan penundaan yang dapat dikonfigurasi melalui delayLongPress
  • android_ripple menambahkan efek ripple Material Design di Android 5+ dengan konfigurasi warna dan bentuk
  • Migrasi dari Touchable memerlukan penggantian efek otomatis dengan styling eksplisit melalui fungsi status
  • Animated + Pressable menciptakan animasi tekanan yang halus dengan useNativeDriver untuk performa

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga