Pressable — moderní komponenta React Native pro zpracování dotyků, která nahrazuje zastaralé TouchableHighlight, TouchableOpacity a TouchableWithoutFeedback. Pressable poskytuje jednotné API s detekcí stavů pressed, hovered a focused. Komponenta se objevila v React Native 0.63 a je doporučena Meta pro všechny nové projekty. Více o komponentě si přečtěte v dokumentaci Meta.
Hlavní
Pressable — komponenta React Native, která poskytuje jednotné rozhraní pro zpracování všech typů dotyků. Na rozdíl od tří různých Touchable komponent (TouchableHighlight, TouchableOpacity, TouchableWithoutFeedback), Pressable je nahrazuje jednou s flexibilním systémem stavů a stylování.
Komponenta byla představena v React Native 0.63 (září 2020). Podle údajů Meta (2026) používá 70% nových projektů na React Native Pressable místo Touchable komponent. Pressable řeší klíčový problém Touchable — roztříštěné API a nutnost přepínání mezi komponentami pro různé efekty.
Na rozdíl od TouchableOpacity, kde je efekt stisku pevně daný (změna průsvitnosti), Pressable poskytuje funkci, která přijímá aktuální stav. Vývojář sám rozhoduje, jak vizuálně reagovat na dotyk: změnit barvu, měřítko, stín nebo kombinaci efektů. To dává plnou kontrolu nad UX.
Pressable definuje tři stavy interakce: pressed (prst na obrazovce), hovered (kurzor nad prvkem na Web/TV), focused (prvek v zaměření klávesnice). Každý stav aktivuje příslušný callback a je předán funkci stylů a funkci renderování potomků.
| Stav | Podmínka | Typická reakce |
|---|---|---|
| pressed | Prst na obrazovce nebo klik stisknutý | Změna průsvitnosti, měřítka, barvy pozadí |
| hovered | Kurzor nad prvkem (Web, TV) | Zvýraznění, stín, podtržení |
| focused | Prvek v zaměření klávesnice | Obrys, ohraničení, změna barvy |
Důležité: hovered a focused fungují pouze na platformách s podporou ukazatele (Web, Android TV, Apple TV). Na mobilních zařízeních je dostupný pouze pressed. Pro multiplatformní aplikace navrhujte vizuální reakce s ohledem na toto omezení.
<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 zahrnuje čtyři hlavní callbacky: onPress (úplné stisknutí s uvolněním), onLongPress (dlouhé stisknutí), onPressIn (začátek dotyku) a onPressOut (konec dotyku). Kombinace onPressIn a onPressOut umožňuje vytvářet vlastní animace.
Další props: delayLongPress (zpoždění dlouhého stisku, výchozí 500 ms), pressRetentionOffset (oblast, za kterou je stisk zrušen), android_ripple (efekt ripple na Androidu). Důležité: Ripple funguje pouze na Android 5+.
<Pressable
onPress={() => console.log('Stisknuto')}
onLongPress={() => console.log('Dlouhý stisk')}
onPressIn={() => console.log('Prst dolů')}
onPressOut={() => console.log('Prst nahoru')}
delayLongPress={300}
android_ripple={{ color: 'rgba(0,0,0,0.1)', borderless: false }}
style={styles.button}>
<Text>Press me</Text>
</Pressable>onPress je volán pouze tehdy, když je prst zvednut uvnitř oblasti komponenty (s přihlédnutím k pressRetentionOffset). Pokud uživatel posune prst mimo hranice, onPress se neaktivuje, což zabraňuje falešným stiskům. onPressOut je volán v každém případě při uvolnění.
hitSlop — prop Pressable, který rozšiřuje oblast dotyku za viditelné hranice komponenty. Je kritický pro malé prvky: ikony, zaškrtávací pole, přepínače. Apple HIG doporučuje minimální velikost touch target 44x44 bodů. hitSlop umožňuje splnit tento požadavek beze změny vizuální velikosti.
hitSlop přijímá objekt { top, bottom, left, right } nebo jediné číslo pro všechny strany. Hodnoty se uvádějí v logických pixelech (dp/pt). Pro ikony 24x24 se doporučuje hitSlop alespoň 10-12 na každé straně pro dosažení 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 — opak hitSlop: určuje oblast, do které může uživatel vyjít za hranice komponenty bez zrušení stisku. Výchozě se rovná hitSlop. Pokud chcete, aby stisk zůstal zachován při opuštění hranic, zvyšte pressRetentionOffset.
Pressable vs Touchable — klíčová otázka při výběru komponenty pro zpracování dotyků. TouchableOpacity, TouchableHighlight a TouchableWithoutFeedback jsou zastaralé komponenty, které nebudou odstraněny, ale nedostávají nové funkce. Meta doporučuje Pressable pro nové projekty.
Hlavní výhody Pressable: jednotné API pro všechny typy efektů, přístup ke stavu pressed pro vlastní stylování, podpora stavů hovered/focused, hitSlop a pressRetentionOffset, callback onLongPress bez další konfigurace. TouchableOpacity je vhodný pouze pro jednoduchou změnu průsvitnosti.
| Scénář | Touchable | Pressable |
|---|---|---|
| Jednoduchý stisk | TouchableOpacity | Pressable + průsvitnost ve style |
| Zvýraznění pozadí | TouchableHighlight | Pressable + backgroundColor |
| Bez vizuálního efektu | TouchableWithoutFeedback | Pressable s prázdným style |
| Dlouhý stisk | onLongPress na libovolném Touchable | onLongPress na Pressable |
| Vlastní animace | Animated + onPressIn/Out | Pressable + useAnimatedStyle |
| Ripple na Androidu | TouchableNativeFeedback | Pressable + android_ripple |
Pressable umožňuje vytvářet komplexní interaktivní prvky s minimem kódu. Níže — příklad animovaného tlačítka se změnou měřítka při stisku a ripple efektem na Androidu. Takové tlačítko nahrazuje kombinaci 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>
);
};Důležité: používejte useNativeDriver: true pro animace v Pressable. To přesune animaci do nativního vlákna a zabraňuje ztrátě snímků při rychlých stiscích. Pro transform a průsvitnost je nativní ovladač podporován na všech platformách.
Často kladené otázky
Ne, Pressable má jiné API. TouchableOpacity automaticky aplikuje průsvitnost při stisku. Pressable vyžaduje explicitní určení stylu pomocí funkce stavu. Náhrada je triviální: předejte style={({ pressed }) => [{ opacity: pressed ? 0.5 : 1 }]}.
Použijte prop android_ripple s objektem { color, borderless }. Barva ripple se uvádí ve formátu rgba. Pro kulatá tlačítka použijte borderless: true. Ripple funguje pouze na Android 5+. Na iOS použijte vlastní animaci.
Pressable má vestavěnou ochranu proti náhodným stiskům během posouvání. Pokud uživatel posouvá seznam, onPress se nevolá. Toto chování lze nakonfigurovat pomocí pressRetentionOffset a delayPressIn.
Použijte prop onLongPress — vestavěná podpora dlouhého stisku. Zpoždění se konfiguruje pomocí delayLongPress (výchozí 500 ms). Pro kontextové nabídky a drag-and-drop kombinujte onLongPress s onPressIn.
Ano, Pressable podporuje focused stav pro navigaci klávesnicí na Android TV, Apple TV a Web. Použijte stylování přes { focused } pro zobrazení zaměření. Na mobilních zařízeních focused stav není relevantní.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také