Reputation: 241
onParentClick = () => {
console.log('Parent is triggered');
}
onChildClick = (event) => {
event.stopPropagation();
console.log('Child is triggered');
}
<TouchableWithoutFeedback onPress={()=> this.onParentClick()}>
<View>
<Text>How to prevent parent click event</Text>
<TouchableOpacity onPress={(event)=> this.onChildClick(event)}>
<Text> Click Me </Text>
</TouchableOpacity>
</View>
</TouchableWithoutFeedback>
<!-- edit description:- there was this end curly brace missing in above,
however the snippet will not run because the language js will not
support it and language html will not be able to format it correctly or run it.
(need to run the snippet on the react native environment like code-pen) -->
Expected: On click of "Click Me", onChildClick() must be called
Issue: On click of "Click Me", onParentClick() is called.
How to prevent parents click event on click of "Click Me"?Result which I get on click of parent is "Parent is triggered" and it works perfect.
But on click on child the result I get is "Parent is triggered".
I guess onChildClick() is not being triggered.
Upvotes: 19
Views: 18494
Reputation: 1920
You'd want to use onTouchEnd not press
This would be the simplest answer:
use this on the inner view at the point where you want the propagation to stop
onTouchEnd={(e) => {
e.stopPropagation()
}}
Upvotes: 0
Reputation: 125
You can simply set the parents pointerEvents property to 'box-none'. By doing so, the parent will not respond to touch events but its child views will get clicked.
<TouchableWithoutFeedback
pointerEvents={'box-none'}
>
<TouchableWithoutFeedback
onPress={()=>{
//onPress here will work
}}
/>
</TouchableWithoutFeedback>
Upvotes: 3
Reputation: 1574
Use TouchableOpacity from gesture handler
import { TouchableOpacity } from "react-native-gesture-handler";
then change your style to containerStyle instead
<TouchableOpacity onPress={props.onPress} containerStyle={styles.container}>
everything should look good now...
Upvotes: 0
Reputation: 31
You need to "swallow" the click event somewhere. It could be in your outer TouchableWithoutFeedback
(ie: change onPress={()=> this.onParentClick()}
to onPress={(e) => e.preventDefault()}
or you could wrap your TouchableOpacity in another touch handler, like below.
<TouchableWithoutFeedback onPress={()=> this.onParentClick()}>
<View>
<Text>How to prevent parent click event</Text>
<TouchableWithoutFeedback onPress={(e) => e.preventDefault()}
<TouchableOpacity onPress={(event)=> this.onChildClick(event)>
<Text> Click Me </Text>
</TouchableOpacity>
</TouchableWithoutFeedback>
</View>
</TouchableWithoutFeedback>
Upvotes: 3
Reputation: 166
A trigger method:
const childPresses = {}
if(canChildPress) {
childPresses.onPress = (event) => {this.onChildClick(event)}
}
return <TouchableWithoutFeedback onPress={()=> this.onParentClick()}>
<View>
<Text>How to prevent parent click event</Text>
<TouchableOpacity {...childPresses} >
<Text> Click Me </Text>
</TouchableOpacity>
</View>
</TouchableWithoutFeedback>
Upvotes: 0
Reputation: 1613
Old question, but I faced the same issue and in my case, the problem was:
import {TouchableOpacity} from 'react-native';
import {TouchableWithoutFeedback} from 'react-native-gesture-handler';
This weird import happened due to automatic suggestion by eslint. Somehow these libraries don't play nicely together, so I changed the above to:
import {TouchableOpacity, TouchableWithoutFeedback} from 'react-native';
Upvotes: 24
Reputation: 847
I had the similar issue, resolved it simply by using zIndex, not only it helped me capture child's onPress but also parent's onPress too, I was able to perform two different operations in a single component
Upvotes: 0
Reputation: 605
The behavior you described works as expected. This is because TouchableOpacity
is a child component of TouchableWithoutFeedback
, and so the click event propagates up the tree, triggering the click event of TouchableWithoutFeedback
. To solve this issue, there is an event.stopPropagation()
method you can call, which will stop the event from bubbling up.
Something like this should work.
onChildClick = (event)=>{
//do your logic here
event.stopPropagation();
}
Upvotes: 1
Reputation: 99
With event.stopPropagation
you can stop event from propagating up to the parents:
https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation
First argument passed onClick is the event itself:
function onChildClick(e) {
e.stopPropagation();
console.log('The link was clicked.');
}
Upvotes: 4