Pressable est un composant moderne de React Native pour la gestion des touches, remplaçant les anciens TouchableHighlight, TouchableOpacity et TouchableWithoutFeedback. Pressable fournit une API unifiée avec la détection des états pressed, hovered et focused. Le composant a été introduit dans React Native 0.63 et est recommandé par Meta pour tous les nouveaux projets. En savoir plus dans la documentation de Meta.
Points clés
Pressable est un composant React Native qui fournit une interface unifiée pour gérer tous les types de touches. Contrairement à trois composants Touchable différents (TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback), Pressable les remplace tous par un système flexible d’états et de styles.
Le composant a été introduit dans React Native 0.63 (septembre 2020). Selon Meta (2026), 70 % des nouveaux projets React Native utilisent Pressable au lieu des composants Touchable. Pressable résout le problème clé de Touchable — une API fragmentée et la nécessité de basculer entre les composants pour différents effets.
Contrairement à TouchableOpacity, où l’effet de pression est fixe (changement d’opacité), Pressable fournit une fonction qui reçoit l’état actuel. Le développeur décide comment réagir visuellement à une pression : changer la couleur, l’échelle, l’ombre ou une combinaison d’effets. Cela donne un contrôle total sur l’UX.
Pressable définit trois états d’interaction : pressed (doigt sur l’écran), hovered (curseur sur l’élément sur le Web/TV), focused (élément au focus clavier). Chaque état déclenche le callback correspondant et est transmis à la fonction de style et à la fonction de rendu enfant.
| État | Condition | Réaction typique |
|---|---|---|
| pressed | Doigt sur l’écran ou clic maintenu | Changement d’opacité, d’échelle ou de couleur de fond |
| hovered | Curseur sur l’élément (Web, TV) | Surbrillance, ombre, soulignement |
| focused | Élément au focus clavier | Contour, bordure, changement de couleur |
Important : hovered et focused fonctionnent uniquement sur les plateformes avec support du pointeur (Web, Android TV, Apple TV). Sur les appareils mobiles, seul pressed est disponible. Pour les applications multiplateformes, concevez les réactions visuelles en tenant compte de cette limitation.
<Pressable
style={({ pressed }) => [
styles.button,
pressed && styles.buttonPressed,
]}
onPress={handlePress}>
{({ pressed }) => (
<Text style={pressed ? styles.textPressed : styles.text}>
{pressed ? 'Release' : 'Press'}
</Text>
)}
</Pressable>L’API de Pressable inclut quatre callbacks principaux : onPress (pression complète avec relâchement), onLongPress (pression longue), onPressIn (début du toucher) et onPressOut (fin du toucher). La combinaison d’onPressIn et onPressOut permet de créer des animations personnalisées.
Props supplémentaires : delayLongPress (délai de pression longue, par défaut 500 ms), pressRetentionOffset (zone au-delà de laquelle la pression est annulée), android_ripple (effet ripple sur Android). Note : Ripple ne fonctionne que sur Android 5+.
<Pressable
onPress={() => console.log('Pressé')}
onLongPress={() => console.log('Pression longue')}
onPressIn={() => console.log('Doigt vers le bas')}
onPressOut={() => console.log('Doigt vers le haut')}
delayLongPress={300}
android_ripple={{ color: 'rgba(0,0,0,0.1)', borderless: false }}
style={styles.button}>
<Text>Press me</Text>
</Pressable>onPress n’est appelé que si le doigt est levé à l’intérieur de la zone du composant (en tenant compte de pressRetentionOffset). Si l’utilisateur déplace son doigt hors des limites, onPress n’est pas déclenché, évitant les fausses pressions. onPressOut est appelé dans tous les cas lors du relâchement.
hitSlop est une prop de Pressable qui étend la zone tactile au-delà des limites visibles du composant. C’est critique pour les petits éléments : icônes, cases à cocher, boutons radio. Apple HIG recommande une taille minimale de cible tactile de 44×44 points. hitSlop permet de respecter cette exigence sans modifier la taille visuelle.
hitSlop accepte un objet { top, bottom, left, right } ou un seul nombre pour tous les côtés. Les valeurs sont spécifiées en pixels logiques (dp/pt). Pour les icônes de 24×24, un hitSlop d’au moins 10–12 de chaque côté est recommandé pour atteindre la cible tactile de 44×44.
<Pressable
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
onPress={handleIconPress}
style={styles.iconButton}>
<Icon name="star" size={24} />
</Pressable>pressRetentionOffset — l’inverse de hitSlop : définit la zone dans laquelle l’utilisateur peut sortir des limites du composant sans annuler la pression. Par défaut, égal à hitSlop. Si vous avez besoin que la pression persiste en sortant des limites, augmentez pressRetentionOffset.
Pressable vs Touchable — une question clé lors du choix d’un composant pour la gestion des touches. TouchableOpacity, TouchableHighlight et TouchableWithoutFeedback sont des composants obsolètes qui ne seront pas supprimés mais ne recevront pas de nouvelles fonctionnalités. Meta recommande Pressable pour les nouveaux projets.
Principaux avantages de Pressable : une API unifiée pour tous les types d’effets, un accès à l’état pressed pour un style personnalisé, la prise en charge des états hovered/focused, hitSlop et pressRetentionOffset, le callback onLongPress sans configuration supplémentaire. TouchableOpacity ne convient que pour les changements simples d’opacité.
| Scénario | Touchable | Pressable |
|---|---|---|
| Pression simple | TouchableOpacity | Pressable + opacity dans style |
| Surbrillance de fond | TouchableHighlight | Pressable + backgroundColor |
| Aucun effet visuel | TouchableWithoutFeedback | Pressable avec style vide |
| Pression longue | onLongPress sur tout Touchable | onLongPress sur Pressable |
| Animation personnalisée | Animated + onPressIn/Out | Pressable + useAnimatedStyle |
| Ripple sur Android | TouchableNativeFeedback | Pressable + android_ripple |
Pressable permet de créer des éléments interactifs complexes avec un minimum de code. Ci-dessous un exemple d’un bouton animé avec changement d’échelle lors de la pression et effet ripple sur Android. Un tel bouton remplace la combinaison 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 : utilisez useNativeDriver : true pour les animations dans Pressable. Cela décharge l’animation sur le thread natif, évitant les chutes d’images lors des pressions rapides. Le pilote natif est pris en charge pour transform et opacity sur toutes les plateformes.
Questions fréquentes
Non, Pressable a une API différente. TouchableOpacity applique automatiquement l’opacité lors de la pression. Pressable nécessite une spécification explicite du style via une fonction d’état. Le remplacement est trivial : passez style={({ pressed }) => [{ opacity: pressed ? 0.5 : 1 }]}.
Utilisez la prop android_ripple avec un objet { color, borderless }. La couleur du ripple est spécifiée au format rgba. Pour les boutons ronds, utilisez borderless : true. Ripple ne fonctionne que sur Android 5+. Sur iOS, utilisez une animation personnalisée.
Pressable dispose d’une protection intégrée contre les pressions accidentelles lors du défilement. Si l’utilisateur fait défiler une liste, onPress n’est pas appelé. Ce comportement peut être configuré via pressRetentionOffset et delayPressIn.
Utilisez la prop onLongPress — prise en charge intégrée de la pression longue. Le délai est configurable via delayLongPress (par défaut 500 ms). Pour les menus contextuels et le glisser-déposer, combinez onLongPress avec onPressIn.
Oui, Pressable prend en charge l’état focused pour la navigation au clavier sur Android TV, Apple TV et le Web. Utilisez le style via { focused } pour afficher le focus. Sur les appareils mobiles, l’état focused n’est pas applicable.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi