![]()
In the previous article, we became true "architects" by using Flexbox for layout and StyleSheet to beautify the application. However, no matter how gorgeous your interface is, it's still just a static picture if nothing happens when the user touches it.
In this article, we will turn the application into a "living" entity that listens to and responds to every swipe and touch from the user. Let's explore how to handle events (Event Handling) in React Native!
1. The surprising truth about the Button component in React Native
If you have ever programmed for the Web, your first instinct when you want to create a button is to look for the <button> tag. React Native also provides a Core Component named <Button>.
However, there is a harsh truth: Professional developers rarely use it.
Why is that? Because the native <Button> component in React Native is very rigid. You cannot add a style property to it. You cannot change the font, you cannot round the corners, and worst of all: Its interface on iOS and Android looks completely different!
To have a beautiful, consistent button across all devices that is 100% customizable using Flexbox, we have to use the component family named Touchable or the newest generation, Pressable.
2. The Era of Touchable: TouchableOpacity
This is the most widely used "hero" for creating buttons throughout the history of React Native.
True to its name (Opacity), when the user touches this component, the entire content inside will dim slightly, creating an extremely natural and familiar visual feedback effect on phones.
How to turn anything into a button
You can wrap TouchableOpacity around a piece of Text, an image, or a massive View block.
Let's take the example of building an interface for a strategy guide app. When users want to lock in a precise synergy team (ensuring role compatibility, such as combining Mid Lane and Jungle), they will press a confirm button.
import React, { useState } from 'react'
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'
export default function SynergySelector() {
const [selectedSynergy, setSelectedSynergy] = useState('No team selected yet')
const handleSelectDuo = () => {
// Update state when the button is pressed.
// Here we choose a standard Mid - Jungle duo.
setSelectedSynergy('Katarina (Mid) & Amumu (Jungle)')
}
return (
<View style={styles.container}>
<Text style={styles.statusText}>Currently selecting: {selectedSynergy}</Text>
{/* Custom designed button with TouchableOpacity */}
<TouchableOpacity
style={styles.button}
onPress={handleSelectDuo} // Catch press event
activeOpacity={0.7} // Customize opacity on press (default is 0.2)
>
<Text style={styles.buttonText}>Confirm Synergy</Text>
</TouchableOpacity>
</View>
)
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
statusText: { fontSize: 18, marginBottom: 20, color: '#333' },
button: {
backgroundColor: '#0984e3',
paddingVertical: 12,
paddingHorizontal: 30,
borderRadius: 8,
elevation: 3, // Create drop shadow on Android
shadowColor: '#000', // Create drop shadow on iOS
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.2,
},
buttonText: { color: 'white', fontSize: 16, fontWeight: 'bold' },
})
(Note: If you use TouchableWithoutFeedback, the button will receive the event but will not have any dimming or color-changing effects. It is often used for hidden actions, for example: Tapping on the empty space outside to hide the keyboard).
3. The Future of Interaction: The Pressable Component
Although TouchableOpacity is great, as your application grows more complex, you sometimes want button effects that are richer than just "dimming". For example: You want the button to change to red when held down, and turn back to blue when released.
That's why React Native introduced Pressable. This is the most modern, flexible component and is recommended to replace the entire Touchable family in new projects.
The power of the pressed state
The most "valuable" feature of Pressable is that it allows you to pass a function into the style property to track whether the button is currently being pressed or not.
import React from 'react'
import { Pressable, Text, StyleSheet, View } from 'react-native'
export default function ModernButton() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Pressable
onPress={() => console.log('Pressed!')}
style={({ pressed }) => [
styles.baseButton,
// If being pressed (pressed = true), change background to dark gray
pressed ? { backgroundColor: '#2d3436' } : { backgroundColor: '#00b894' },
]}
>
{({ pressed }) => <Text style={styles.text}>{pressed ? 'Holding tight...' : 'Touch me!'}</Text>}
</Pressable>
</View>
)
}
const styles = StyleSheet.create({
baseButton: {
padding: 15,
borderRadius: 10,
minWidth: 150,
alignItems: 'center',
},
text: { color: 'white', fontWeight: 'bold' },
})
With Pressable, you have 100% control over the interactive feel without having to write complex code to track animations.
4. Extended Touch Event Types
Both TouchableOpacity and Pressable support more event milestones than just a single tap (onPress). You can leverage them to create advanced features:
onPress: Triggered when the user touches and releases (The most common click action).onLongPress: Triggered when the user presses and holds the button for a sufficiently long time (about 500ms). Often used to open a sub-menu or delete an item.onPressIn: Triggered the exact moment the finger touches the screen (even before releasing).onPressOut: Triggered the moment the finger leaves the screen.
Pro tip: Pressable also has a hitSlop property. If you have a small button (like an X button to close a popup), you can use hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }} to expand the touchable area, making it easier for users with larger fingers to hit it without changing the actual visual size of the button on the interface.
Conclusion: The application is now interactive
For a React Native application to respond smoothly to interactions:
- Avoid using the default
<Button>if you want a highly aesthetic and consistent interface. - Use
TouchableOpacityfor cases involving quick buttons that need a simple dimming effect. - Switch to using
Pressablefor new projects or when you need deep customization of the display state when pressed, as well as leveraginghitSlopto optimize user experience (UX).
Up to this point, you know how to draw interfaces and make them "listen". But real-world applications often contain hundreds or thousands of data items (like a Facebook newsfeed or a product list). If you display them all at once, the phone will immediately freeze!
To solve this tricky problem, we will move on to the next lessons.