I have the following React Native code that runs the press() method when a user taps an image. I want to get the itemIndex prop from the event object. I set a break point in the press method and added some expressions to the Watch. From the Watch I determined that the target (event origination) from the event is the Image which is correct. The itemIndex prop is also available. The element being processed is the currentTarget, the Watch sees it's a "RCTView" and I was expecting a TouchableOpacity, so maybe underneath TouchableOpacity is a View? The currentTarget itemIndex prop is undefined, why? How can I get the props from the currentTarget?
I want to do it this way to avoid creating addition methods for each rendered item.
FYI,
ref={(c) => this._input = c}
will not work because it's being run in a loop.
onPress={(e) => this.press(e, i)}
creates a new function which I'm trying to avoid.
Watch
currentTarget._currentElement.type.displayName: "RCTView"
press: function(event){
var currentTarget = ReactNativeComponentTree.getInstanceFromNode(event.currentTarget);
var target = ReactNativeComponentTree.getInstanceFromNode(event.target);
var currentTargetIndex = currentTarget._currentElement.props.itemIndex;
var targetIndex = target._currentElement.props.itemIndex;
var url = this.state.data.items[currentTargetIndex].url;
Linking.openURL(url).catch(err => console.error('An error occurred', err));
},
render: function() {
return (
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={styles.galleryView}>
{
this.state.data.items.map((data, i) =>
<TouchableOpacity itemIndex={i} key={i} activeOpacity={0.5} onPress={this.press} >
<Image itemIndex={i} key={i} source={{uri:data.previewImageUri}} style={styles.galleryImage} />
</TouchableOpacity>
)
}
</ScrollView>
);
}
I actually came across this same issue recently, I found two different ways you could approach this. The easier way of doing it is altering your onPress
to pass an index to your press function, this is the 2nd way of doing it:
press: function(event, index){
var url = this.state.data.items[index].url;
Linking.openURL(url).catch(err => console.error('An error occurred', err));
},
render: function() {
return (
<ScrollView
horizontal={true}
showsHorizontalScrollIndicator={false}
style={styles.galleryView}
>
{
this.state.data.items.map((data, i) =>
<Images data={data} key={i} index={i} press={this.press} />
)
}
</ScrollView>
);
}
const Images = (props) => {
const imageClicked = (e) => {
props.press(e, props.index);
}
return (
<TouchableOpacity activeOpacity={0.5} onPress={imageClicked} >
<Image source={{uri:props.data.previewImageUri}} style={styles.galleryImage} />
</TouchableOpacity>
)
}
You could make your event handler a curried function that accepts extra parameters.
//Curried function for onPress event handler
handleOnPress = (someId, someProp) => event => {
//USE someProp ABOVE TO ACCESS PASSED PROP, WHICH WOULD BE undefined IN THIS CASE
//Use event parameter above to access event object if you need
console.log(someProp)
this.setState({
touchedId: someId
})
}
Checkout the working snack below
https://snack.expo.io/@prashand/accessing-props-from-react-native-touch-event
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With