Search code examples
androidiosreact-nativereact-native-gesture-handler

How can I make application components swipeable in React Native?


I'm learning how to build mobile applications with React Native and I'm following a React native course by Programming with Mosh. However, I ran into a problem where I can't get my program to allow me to swipe left to delete a list item. Swiping left should open up a red square.

I have tried reading the documentation, googling answers and watching youtube videos, but I have made 0 progress :(.

Here's my code for the ListItem component:

import React from 'react';
import {View, StyleSheet, Image, TouchableHighlight } from 'react-native';
import Swipeable from 'react-native-gesture-handler/Swipeable';

import colors from '../config/colors';
import AppText from './AppText';


function ListItem({title, subTitle, image, onPress, renderRightActions}) {
    return (
        <Swipeable renderRightActions={renderRightActions}>
            <TouchableHighlight 
                underlayColor={colors.lightGrey}
                onPress={onPress}>
                <View style={styles.container}>
                    <Image style={styles.image} source={image} />
                    <View style={styles.textContainer}>
                        <AppText style={styles.title}>{title}</AppText>
                        <AppText style={styles.subTitle}>{subTitle}</AppText>
                    </View>
                </View>
            </TouchableHighlight>
        </Swipeable>
    );
}

and here is the code for when I actually use it:

import React from 'react';
import {StyleSheet, FlatList} from 'react-native';

import ListItem from '../components/ListItem';
import Screen from '../components/Screen';
import ListItemSeperator from '../components/ListItemSeperator';
import ListItemDeleteAction from '../components/ListItemDeleteAction';

function MessagesScreen(props) {
    return (
        <Screen>
            <FlatList
                data={messages}
                keyExtractor={message => message.id.toString()}
                renderItem={({item}) => 
                    <ListItem
                        title={item.title}
                        subTitle={item.description}
                        image={item.image}
                        onPress={() => console.log('message selected', item)}
                        renderRightActions={ListItemDeleteAction}/>
                    }
            ItemSeparatorComponent={ListItemSeperator}
            />
        </Screen>

Where the renderRightActions={ListItemDeleteAction} is just another component which holds a View with some style:

function ListItemDeleteAction(props) {
    return (
        <View style={styles.container}></View>
    );
}

Any help would be highly appreciated, Thank you in advance!


Solution

  • The answer was that I needed to use GestureHandlerRootView to wrap everything!

    import React from 'react';
    import {View, StyleSheet, Image, TouchableHighlight } from 'react-native';
    import Swipeable from 'react-native-gesture-handler/Swipeable';
    import {GestureHandlerRootView} from 'react-native-gesture-handler';
    
    import colors from '../config/colors';
    import AppText from './AppText';
    
    
    function ListItem({title, subTitle, image, onPress, renderRightActions}) {
        return (
            <GestureHandlerRootView>
                <Swipeable renderRightActions={renderRightActions}>
                    <TouchableHighlight 
                        underlayColor={colors.lightGrey}
                        onPress={onPress}>
                        <View style={styles.container}>
                            <Image style={styles.image} source={image} />
                            <View style={styles.textContainer}>
                                <AppText style={styles.title}>{title}</AppText>
                                <AppText style={styles.subTitle}>{subTitle}</AppText>
                            </View>
                        </View>
                    </TouchableHighlight>
                </Swipeable>
            </GestureHandlerRootView>
        );
    }
    

    Now the component works on android.