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 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.
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.
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.
| Status | Kondisi | Reaksi tipikal |
|---|---|---|
| pressed | Jari di layar atau klik ditekan | Perubahan opacity, skala, warna latar |
| hovered | Kursor di atas elemen (Web, TV) | Penyorotan, bayangan, garis bawah |
| focused | Elemen dalam fokus keyboard | Garis 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.
<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 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+.
<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 — 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.
<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 — 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.
| Skenario | Touchable | Pressable |
|---|---|---|
| Tekanan sederhana | TouchableOpacity | Pressable + opacity di style |
| Penyorotan latar | TouchableHighlight | Pressable + backgroundColor |
| Tanpa efek visual | TouchableWithoutFeedback | Pressable dengan style kosong |
| Tekanan lama | onLongPress pada Touchable mana pun | onLongPress pada Pressable |
| Animasi kustom | Animated + onPressIn/Out | Pressable + useAnimatedStyle |
| Ripple di Android | TouchableNativeFeedback | Pressable + android_ripple |
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.
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
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 }]}.
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.
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.
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.
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
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.
Baca juga