Pressable — o componentă modernă React Native pentru gestionarea atingerilor, care înlocuiește TouchableHighlight, TouchableOpacity și TouchableWithoutFeedback învechite. Pressable oferă un API unificat cu detectarea stărilor pressed, hovered și focused. Componenta a apărut în React Native 0.63 și este recomandată de Meta pentru toate proiectele noi. Citiți mai multe despre componentă în documentația Meta.
Principalele
Pressable — o componentă React Native care oferă o interfață unificată pentru gestionarea tuturor tipurilor de atingeri. Spre deosebire de trei componente Touchable diferite (TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback), Pressable le înlocuiește pe toate cu una singură, având un sistem flexibil de stări și stilizare.
Componenta a fost introdusă în React Native 0.63 (septembrie 2020). Conform datelor Meta (2026), 70% din proiectele noi pe React Native folosesc Pressable în locul componentelor Touchable. Pressable rezolvă problema cheie a Touchable — API-ul împrăștiat și necesitatea de a comuta între componente pentru efecte diferite.
Spre deosebire de TouchableOpacity, unde efectul de apăsare este strict definit (schimbarea opacității), Pressable oferă o funcție care primește starea curentă. Dezvoltatorul decide singur cum să reacționeze vizual la atingere: să schimbe culoarea, scala, umbra sau o combinație de efecte. Acest lucru oferă control total asupra UX.
Pressable definește trei stări de interacțiune: pressed (degetul pe ecran), hovered (cursorul deasupra elementului pe Web/TV), focused (elementul în focalizarea tastaturii). Fiecare stare activează callback-ul corespunzător și este transmisă funcției de stiluri și funcției de randare a copiilor.
| Stare | Condiție | Reacție tipică |
|---|---|---|
| pressed | Degetul pe ecran sau clicul apăsat | Schimbarea opacității, scalei, culorii de fundal |
| hovered | Cursorul deasupra elementului (Web, TV) | Iluminare, umbră, subliniere |
| focused | Elementul în focalizarea tastaturii | Contur, bordură, schimbare de culoare |
Important: hovered și focused funcționează doar pe platformele cu suport pentru indicator (Web, Android TV, Apple TV). Pe dispozitivele mobile este disponibilă doar starea pressed. Pentru aplicații cross-platform, proiectați reacțiile vizuale ținând cont de această limitare.
<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 include patru callback-uri principale: onPress (apăsare completă cu eliberare), onLongPress (apăsare lungă), onPressIn (începutul atingerii) și onPressOut (sfârșitul atingerii). Combinația onPressIn și onPressOut permite crearea de animații personalizate.
Props-uri suplimentare: delayLongPress (întârzierea apăsării lungi, implicit 500 ms), pressRetentionOffset (zona dincolo de care apăsarea este anulată), android_ripple (efectul ripple pe Android). Important: Ripple funcționează doar pe Android 5+.
<Pressable
onPress={() => console.log('Apăsat')}
onLongPress={() => console.log('Apăsare lungă')}
onPressIn={() => console.log('Degetul în jos')}
onPressOut={() => console.log('Degetul în sus')}
delayLongPress={300}
android_ripple={{ color: 'rgba(0,0,0,0.1)', borderless: false }}
style={styles.button}>
<Text>Press me</Text>
</Pressable>onPress este apelat doar când degetul este ridicat în interiorul zonei componentei (ținând cont de pressRetentionOffset). Dacă utilizatorul mută degetul dincolo de limite, onPress nu se declanșează, prevenind apăsările false. onPressOut este apelat în orice caz la eliberare.
hitSlop — un prop Pressable care extinde zona de atingere dincolo de limitele vizibile ale componentei. Este critic pentru elemente mici: icoane, checkbox-uri, butoane radio. Apple HIG recomandă o dimensiune minimă a țintei de atingere de 44x44 de puncte. hitSlop permite respectarea acestei cerințe fără a modifica dimensiunea vizuală.
hitSlop acceptă un obiect { top, bottom, left, right } sau un singur număr pentru toate părțile. Valorile sunt specificate în pixeli logici (dp/pt). Pentru icoanele de 24x24, hitSlop-ul recomandat este de minimum 10-12 pe fiecare parte pentru a atinge ținta de atingere de 44x44.
<Pressable
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
onPress={handleIconPress}
style={styles.iconButton}>
<Icon name="star" size={24} />
</Pressable>pressRetentionOffset — inversul hitSlop: definește zona în care utilizatorul poate ieși dincolo de limitele componentei fără a anula apăsarea. Implicit este egal cu hitSlop. Dacă aveți nevoie ca apăsarea să se păstreze la ieșirea din limite, măriți pressRetentionOffset.
Pressable vs Touchable — întrebarea cheie la alegerea componentei pentru gestionarea atingerilor. TouchableOpacity, TouchableHighlight și TouchableWithoutFeedback sunt componente învechite care nu vor fi șterse, dar nu primesc funcționalități noi. Meta recomandă Pressable pentru proiecte noi.
Principalele avantaje ale Pressable: API unificat pentru toate tipurile de efecte, acces la starea pressed pentru stilizare personalizată, suport pentru stările hovered/focused, hitSlop și pressRetentionOffset, callback onLongPress fără configurare suplimentară. TouchableOpacity este potrivit doar pentru simpla modificare a transparenței.
| Scenariu | Touchable | Pressable |
|---|---|---|
| Apăsare simplă | TouchableOpacity | Pressable + opacitate în style |
| Iluminare fundal | TouchableHighlight | Pressable + backgroundColor |
| Fără efect vizual | TouchableWithoutFeedback | Pressable cu style gol |
| Apăsare lungă | onLongPress pe orice Touchable | onLongPress pe Pressable |
| Animație personalizată | Animated + onPressIn/Out | Pressable + useAnimatedStyle |
| Ripple pe Android | TouchableNativeFeedback | Pressable + android_ripple |
Pressable permite crearea de elemente interactive complexe cu un minim de cod. Mai jos — un exemplu de buton animat cu schimbarea scalei la apăsare și efect ripple pe Android. Un astfel de buton înlocuiește combinația 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>
);
};Important: utilizați useNativeDriver: true pentru animații în Pressable. Acest lucru mută animația în thread-ul nativ, prevenind pierderile de cadre la apăsări rapide. Pentru transform și opacitate, driver-ul nativ este suportat pe toate platformele.
Întrebări frecvente
Nu, Pressable are un API diferit. TouchableOpacity aplică automat opacitatea la apăsare. Pressable necesită specificarea explicită a stilului prin funcția de stare. Înlocuirea este trivială: transmiteți style={({ pressed }) => [{ opacity: pressed ? 0.5 : 1 }]}.
Folosiți prop-ul android_ripple cu un obiect { color, borderless }. Culoarea ripple se specifică în format rgba. Pentru butoane rotunde folosiți borderless: true. Ripple funcționează doar pe Android 5+. Pe iOS folosiți o animație personalizată.
Pressable are protecție încorporată împotriva apăsărilor accidentale în timpul derulării. Dacă utilizatorul derulează o listă, onPress nu este apelat. Acest comportament poate fi configurat prin pressRetentionOffset și delayPressIn.
Folosiți prop-ul onLongPress — suport încorporat pentru apăsare lungă. Întârzierea se configurează prin delayLongPress (implicit 500 ms). Pentru meniuri contextuale și drag-and-drop, combinați onLongPress cu onPressIn.
Da, Pressable suportă starea focused pentru navigarea cu tastatura pe Android TV, Apple TV și Web. Folosiți stilizarea prin { focused } pentru afișarea focalizării. Pe dispozitivele mobile, starea focused nu este relevantă.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și