I'd like the style of a button in my app to change when it is being pressed. What is the best way to do this?
-
Do you need it to change while it is being pressed only, and change back when the user is not pressing it? Or do you need to change it when it is touched, and keep the changed state after the touch is stopped? – Nader Dabit Jan 06 '16 at 12:58
-
To change back when the user is not pressing it. – domi91c Jan 06 '16 at 14:40
-
This [solution](https://stackoverflow.com/questions/34088496/how-to-change-image-and-text-color-when-clicking-using-react-native/52155810#52155810) worked on me – Maybelle Pacate Nov 06 '18 at 08:50
5 Answers
Use TouchableHighlight
.
Here an example:
import React from 'react';
import { TouchableHighlight, View, Text, StyleSheet } from 'react-native';
export default function Button() {
var [ isPress, setIsPress ] = React.useState(false);
var touchProps = {
activeOpacity: 1,
underlayColor: 'blue', // <-- "backgroundColor" will be always overwritten by "underlayColor"
style: isPress ? styles.btnPress : styles.btnNormal, // <-- but you can still apply other style changes
onHideUnderlay: () => setIsPress(false),
onShowUnderlay: () => setIsPress(true),
onPress: () => console.log('HELLO'), // <-- "onPress" is apparently required
};
return (
<View style={styles.container}>
<TouchableHighlight {...touchProps}>
<Text>Click here</Text>
</TouchableHighlight>
</View>
);
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
btnNormal: {
borderColor: 'blue',
borderWidth: 1,
borderRadius: 10,
height: 30,
width: 100,
},
btnPress: {
borderColor: 'blue',
borderWidth: 1,
height: 30,
width: 100,
}
});

- 917
- 1
- 8
- 12
-
This is really helpful! And `onHideUnderlay` & `onShowUnderlay` methods are not conflict with `onPress`. This kinda get me confused a little. – Bruce Lee Sep 24 '16 at 12:11
-
7Just a note that `
` must also contain an `onPress` handler for this to work (as of React Native v0.34) – rnevius Oct 08 '16 at 13:33 -
Did not know about `onHideUnderlay` & `onShowUnderlay`! Was googling forever to find out how to accomplish something like this. Thank you! – Greg Blass Oct 25 '17 at 19:28
-
Using this method, the style changes only after you hold your fingers on the button ... it will not change only on a tap. – P.Lorand Nov 08 '17 at 17:01
-
1Important to note that `underlayColor` is required along with `activeOpacity={1}` for this to work. – instanceof Dec 19 '19 at 09:38
-
React Native now provides a new Pressable
component that can detect various stages of press interactions.
So, in order to change the color(in general any style) of the component, refer below example:
<Pressable
style={({ pressed }) => [{ backgroundColor: pressed ? 'black' : 'white' }, styles.btn ]}>
{({ pressed }) => (
<Text style={[{ color: pressed ? 'white' : 'black' }, styles.btnText]}>
{text}
</Text>
)}
</Pressable>
Code breakdown:
style={({ pressed }) => [{ backgroundColor: pressed ? 'black' : 'white' }, styles.btn ]}
Here the style prop receives pressed(boolean) that reflects whether Pressable
is pressed or not and returns an array of styles.
{({ pressed }) => (
<Text style={[{ color: pressed ? 'white' : 'black' }, styles.btnText]}>
{text}
</Text>
)}
Here the text style too can be modified as the pressed
is also accessible to the children of Pressable
component.

- 1,433
- 2
- 17
- 22
Use the prop:
underlayColor
<TouchableHighlight style={styles.btn} underlayColor={'gray'} />

- 4,375
- 2
- 21
- 25

- 762
- 6
- 9
-
1`underlayColor`will be displayed with a slight opacity. And setting `activeOpacity` to 0 will completely ignore any styles applied to the unpressed state. – Naoto Ida Jun 29 '17 at 06:26
This is Besart Hoxhaj's answer in ES6. When i answer this, React Native is 0.34.
import React from "react";
import { TouchableHighlight, Text, Alert, StyleSheet } from "react-native";
export default class TouchableButton extends React.Component {
constructor(props) {
super(props);
this.state = {
pressed: false
};
}
render() {
return (
<TouchableHighlight
onPress={() => {
// Alert.alert(
// `You clicked this button`,
// 'Hello World!',
// [
// {text: 'Ask me later', onPress: () => console.log('Ask me later pressed')},
// {text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
// {text: 'OK', onPress: () => console.log('OK Pressed')},
// ]
// )
}}
style={[
styles.button,
this.state.pressed ? { backgroundColor: "green" } : {}
]}
onHideUnderlay={() => {
this.setState({ pressed: false });
}}
onShowUnderlay={() => {
this.setState({ pressed: true });
}}
>
<Text>Button</Text>
</TouchableHighlight>
);
}
}
const styles = StyleSheet.create({
button: {
padding: 10,
borderColor: "blue",
borderWidth: 1,
borderRadius: 5
}
});

- 571
- 1
- 5
- 20

- 4,177
- 3
- 28
- 26
use something like that :
class A extends React.Component {
constructor(props){
super(props);
this.state = {
onClicked: false
}
this.handlerButtonOnClick = this.handlerButtonOnClick.bind(this);
}
handlerButtonOnClick(){
this.setState({
onClicked: true
});
}
render() {
var _style;
if (this.state.onClicked){ // clicked button style
_style = {
color: "red"
}
}
else{ // default button style
_style = {
color: "blue"
}
}
return (
<div>
<button
onClick={this.handlerButtonOnClick}
style={_style}>Press me !</button>
</div>
);
}
}
If you use an external CSS, you can use className in place of style property :
render() {
var _class = "button";
var _class.concat(this.state.onClicked ? "-pressed" : "-normal") ;
return (
<div>
<button
onClick={this.handlerButtonOnClick}
className={_class}>Press me !</button>
</div>
);
}
It doesn't really matter how do you apply your CSS. Keep your eyes on the "handlerButtonOnClick" method.
When the state change, the component is re-rendered ("render" method is called again).
Good luck ;)

- 127
- 5
-
react-native doesn't have a button component. It uses touchableHighlight, touchableNativeFeedback among others. – Nico Mar 19 '16 at 17:03
-
the problem is not about react-native or not... the problem is about to understand how & when react apply styles on component. The flow is always the same : handleEvent -> handler -> setState -> render. My answer is about this flow, not about react-native – sami ghazouane Mar 30 '16 at 09:26
-
1Update - React Native added the [``](https://facebook.github.io/react-native/docs/button.html) component in [version 0.37](https://github.com/facebook/react-native/releases/tag/v0.37.0) – Hastig Zusammenstellen Jun 06 '18 at 10:33