React native onPress with TouchableWithoutFeedback is not working

29.8k Views Asked by At

I am developing a simple React Native application for learning purpose. I am just taking my initial step to get into the React Native world. But in this very early stage, I am having problems. I cannot get a simple touch event working. I am implementing touch event using TouchableWithoutFeedback. This is my code.

class AlbumList extends React.Component {

    constructor(props)
    {
        super(props)
        this.state = {
            displayList : true
        }
    }
    componentWillMount() {
        this.props.fetchAlbums();
    }

    albumPressed(album)
    {
        console.log("Touch event triggered")
    }

    renderAlbumItem = ({item: album}) => {
        return (
                <TouchableWithoutFeedback onPress={this.albumPressed.bind(this)}>
                    <Card>
                        <CardSection>
                            <Text>{album.artist}</Text>
                        </CardSection>
                        <CardSection>
                            <Text>{album.title}</Text>
                        </CardSection>
                    </Card>
                </TouchableWithoutFeedback>
            )
    }

    render() {
        let list;
        if (this.state.displayList) {
            list = <FlatList
                data={this.props.albums}
                renderItem={this.renderAlbumItem}
                keyExtractor={(album) => album.title}
            />
        }

        return (
            list
        )
    }
}

const mapStateToProps = state => {
    return state.albumList;
}

const mapDispatchToProps = (dispatch, ownProps) => {
    return bindActionCreators({
        fetchAlbums : AlbumListActions.fetchAlbums
    }, dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(AlbumList);

As you can see, I am implementing touch event on the list item. But it is not triggering at all when I click on the card on Simulator. Why? How can I fix it?

8

There are 8 best solutions below

2
On BEST ANSWER

You should wrap your content in component like this:

<TouchableWithoutFeedback>
 <View>
  <Your components...>
 </View>
</TouchableWithoutFeedback>
0
On

For some unknown reasons, even wrapping the children in a View inside the TouchableWithoutFeedback wasn't working for me. What fixed it for me is replacing TouchableWithoutFeedback with the new Pressable component introduced in 2020.

Also wrapping the child with a View or wrapping the whole TouchableWithoutFeedback with another View or setting the pointerEvents="none" of the inner View as suggested by other users seems like workarounds.

For me the new component: Pressable seems like a good choice to replace the TouchableWithoutFeedback component, it also offers a lot of versatility if you need.

So, using Pressable, the code in the question can be modified like so:

<Pressable onPress={this.albumPressed.bind(this)}>
  <Card>
    <CardSection>
      <Text>{album.artist}</Text>
    </CardSection>
    <CardSection>
      <Text>{album.title}</Text>
    </CardSection>
  </Card>
</Pressable>
1
On

For those who struggle with this issue in react-native 0.64, and wrapping it in just a View doesn't work, try this:

  <TouchableWithoutFeedback onPress={onPress}>
    <View pointerEvents="none">
      <Text>Text</Text>
    </View>
  </TouchableWithoutFeedback>
1
On

In my case i accidentally imported TouchableWithoutFeedback from react-native-web instead of react-native. After importing from react-native everything worked as expected.

0
On

In more recent React Native versions, just use Pressable instead: https://reactnative.dev/docs/pressable

1
On

Can be used with <TouchableOpacity activeOpacity={1.0}> </TouchableOpacity>

0
On

In my case, there was a shadow underneath, which caused instability. What I did to solve it was quite simple: zIndex: 65000

<View style={{ zIndex: 65000 }}>
   <TouchableWithoutFeedback onPressIn={() =>  {}>
     <View>
     </View>
   </TouchableWithoutFeedback>
</View>
0
On

TouchableWithoutFeedback always needs to have child View component. So a component that composes a View isn't enough.

So instead of

<TouchableWithoutFeedback onPressIn={...} onPressOut={...} onPress={...}>
  <MyCustomComponent />
</TouchableWithoutFeedback>

use:

<TouchableWithoutFeedback onPressIn={...} onPressOut={...} onPress={...}>
  <View>
    <MyCustomComponent />
  </View>
</TouchableWithoutFeedback>

See the github issue for more info