Pressable — савремена React Native компонента за обраду додира, која замењује застареле TouchableHighlight, TouchableOpacity и TouchableWithoutFeedback. Pressable пружа јединствени API са детекцијом стања pressed, hovered и focused. Компонента се појавила у React Native 0.63 и је препоручена од стране Meta-а за све нове пројекте. Више о компоненти прочитајте у Meta документацији.
Главно
Pressable — React Native компонента која пружа јединствени интерфејс за обраду свих врста додира. За разлику од три различите Touchable компоненте (TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback), Pressable их замењује једном са флексибилним системом стања и стилизације.
Компонента је представљена у React Native 0.63 (септембар 2020). Према подацима Meta (2026), 70% нових пројеката на React Native користи Pressable уместо Touchable компонената. Pressable решава кључни проблем Touchable — разбацани API и потребу за пребацивањем између компонената за различите ефекте.
За разлику од TouchableOpacity, где је ефекат притиска чврсто дефинисан (промена опакова), Pressable пружа функцију која прима тренутно стање. Програмер сам одлучује како визуелно реаговати на додир: променити боју, размер, сенку или комбинацију ефеката. То пружа пуну контролу над UX-ом.
Pressable дефинише три стања интеракције: pressed (прст на екрану), hovered (курсор изнад елемента на Web/TV), focused (елемент у фокусу тастатуре). Свако стање активира одговарајући повратни позив и прослевђује се функцији стилова и функцији рендеровања деце.
| Стање | Услов | Типична реакција |
|---|---|---|
| pressed | Прст на екрану или клик притиснут | Промена опакова, размера, боје позадине |
| hovered | Курсор изнад елемента (Web, TV) | Осветљавање, сенка, подвлачење |
| focused | Елемент у фокусу тастатуре | Контура, ивица, промена боје |
Важно: hovered и focused раде само на платформама са подршком показивача (Web, Android TV, Apple TV). На мобилним уређајима доступно је само pressed. За вишеплатформске апликације, дизајнирајте визуелне реакције имајући у виду ово ограничење.
<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 укључује четири главна повратна позива: onPress (пуно притискање са отпуштањем), onLongPress (дуго притискање), onPressIn (почетак додира) и onPressOut (крај додира). Комбинација onPressIn и onPressOut омогућава стварање прилагођених анимација.
Додатни props: delayLongPress (кашњење дугог притиска, подразумевано 500 ms), pressRetentionOffset (област изван које се притисак поништава), android_ripple (ripple ефекат на Android-у). Важно: Ripple ради само на Android 5+.
<Pressable
onPress={() => console.log('Притиснуто')}
onLongPress={() => console.log('Дуго притискање')}
onPressIn={() => console.log('Прст доле')}
onPressOut={() => console.log('Прст горе')}
delayLongPress={300}
android_ripple={{ color: 'rgba(0,0,0,0.1)', borderless: false }}
style={styles.button}>
<Text>Press me</Text>
</Pressable>onPress се позива само ако се прст подигне унутар области компоненте (узимајући у обзир pressRetentionOffset). Ако корисник помакне прст изван граница, onPress се не окида, што спречава лажне притиске. onPressOut се позива у сваком случају при отпуштању.
hitSlop — Pressable prop који проширује област додира изван видљивих граница компоненте. Критично је за мале елементе: иконице, чекбоксове, радио дугмиће. Apple HIG препоручује минималну величину touch target од 44x44 тачака. hitSlop омогућава испуњење овог захтева без промене визуелне величине.
hitSlop прихвата објекат { top, bottom, left, right } или један број за све стране. Вредности се наводе у логичким пикселима (dp/pt). За иконице 24x24, препоручује се hitSlop од најмање 10-12 сваке стране да би се постигао touch target од 44x44.
<Pressable
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
onPress={handleIconPress}
style={styles.iconButton}>
<Icon name="star" size={24} />
</Pressable>pressRetentionOffset — обрнути hitSlop: одређује област у којој корисник може изћи изван граница компоненте а да се притисак не поништи. Подразумевано једнак као hitSlop. Ако желите да се притисак задржи при изласку изван граница, повећајте pressRetentionOffset.
Pressable vs Touchable — кључно питање при избору компоненте за обраду додира. TouchableOpacity, TouchableHighlight и TouchableWithoutFeedback су застареле компоненте које неће бити уклоњене, али не добијају нове могућности. Meta препоручује Pressable за нове пројекте.
Главне предности Pressable: јединствени API за све врсте ефеката, приступ стању pressed за прилагођену стилизацију, подршка стања hovered/focused, hitSlop и pressRetentionOffset, повратни позив onLongPress без додатног подешавања. TouchableOpacity је погодан само за једноставну промену прозирности.
| Сценаријо | Touchable | Pressable |
|---|---|---|
| Једноставно притискање | TouchableOpacity | Pressable + опаков у style |
| Осветљавање позадине | TouchableHighlight | Pressable + backgroundColor |
| Без визуелног ефекта | TouchableWithoutFeedback | Pressable са празним style |
| Дуго притискање | onLongPress на било којем Touchable | onLongPress на Pressable |
| Прилагођена анимација | Animated + onPressIn/Out | Pressable + useAnimatedStyle |
| Ripple на Android-у | TouchableNativeFeedback | Pressable + android_ripple |
Pressable омогућава стварање сложених интерактивних елемената са минимумом кода. Испод је пример анимираног дугмета са променом размера при притиску и ripple ефектом на Android-у. Такво дугме замењује комбинацију 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>
);
};Важно: користите useNativeDriver: true за анимације у Pressable. То пребацује анимацију у нативни ток, спречавајући падове кадрова при брзим притисцима. За transform и опаков, нативни погон је подржан на свим платформама.
Често постављана питања
Не, Pressable има другачији API. TouchableOpacity аутоматски примењује опаков при притиску. Pressable захтева јасно наводење стила кроз функцију стања. Замена је једноставна: проследите style={({ pressed }) => [{ opacity: pressed ? 0.5 : 1 }]}.
Користите prop android_ripple са објектом { color, borderless }. Боја ripple-а се наводи у rgba формату. За округле дугмиће користите borderless: true. Ripple ради само на Android 5+. На iOS-у користите прилагођену анимацију.
Pressable има уграђену заштиту од случајних притисака током скроловања. Ако корисник скролује листу, onPress се не позива. Ово понашање се може конфигурисати кроз pressRetentionOffset и delayPressIn.
Користите prop onLongPress — уграђена подршка дугог притиска. Кашњење се подешава кроз delayLongPress (подразумевано 500 ms). За контекстне меније и drag-and-drop, комбинирајте onLongPress са onPressIn.
Да, Pressable подржава focused стање за навигацију тастатуром на Android TV, Apple TV и Web-у. Користите стилизацију кроз { focused } за приказ фокуса. На мобилним уређајима focused стање није релевантно.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође