Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete on swipe is not closing the Swipeable React native

Tags:

react-native

I am using react-native-gesture-handler for swipe delete purpose.it is doing fine but whenever I swipe to delete it deletes that row but not closing the Swipeable. I have to swipe left to close it. Not understanding why this is happening. I am providing the code here:-

import Swipeable from 'react-native-gesture-handler/Swipeable';

    LeftActions = (progress,dragX)=>{
  const scale = dragX.interpolate({
    inputRange: [0, 100],
    outputRange: [0, 1],
    extrapolate: 'clamp',
  });
  return(
    <View style={styles.leftAction}>
      <Animated.Text 
      style={[
          styles.textAction,
          {
            transform:[{
              scale
            }]
          }
        ]}>Delete</Animated.Text>
    </View>
  )
}

class SwipeList extends React.Component {
constructor(props) {
    super(props);
}

SwipeableRow = ({ item, index }) => {
  return (
      <Swipeable
        renderLeftActions={LeftActions}
        renderRightActions={RightActions}
        onSwipeableLeftOpen={()=>this.deleteRow(index)}
      >
        <View style={{paddingHorizontal:10,backgroundColor:'#fff',paddingVertical:20}}>
          <Text style={styles.fromText}>{item.from}</Text>
          <Text numberOfLines={2} style={styles.messageText}>
            {item.message}
          </Text>
        </View>
       </Swipeable>
    );
};
state = {
    list:[
      {
        from: "1",
        when: '3:11 PM',
        message: 'message 1',
      },
      {
        from: '2',
        when: '11:46 AM',
        message:'message 2',
      }
    ]
}

deleteRow = (index) =>{
  this.setState(prev=>{
    return{
      list:prev.list.filter((single,i)=>{
        if(index!=i){
          return single
        }
      })
    }
  })

}

render() {
    return (
        <FlatList
          data={this.state.list}
          ItemSeparatorComponent={() => <View style={styles.separator} />}
          renderItem={this.SwipeableRow}
          keyExtractor={(item, index) => `message ${index}`}
        />
      );
}

}

Here are the styles I am using:-

const styles = StyleSheet.create({
    leftAction:{
                  backgroundColor:'violet',
                  justifyContent:'center',
                  flex:1
                }
     });

Here is an animation of what is happening:- enter image description here

May be I am doing some silly mistake, I am new to React Native. It will be helpful if I get any kind of guidance.

like image 718
Sandip Nag Avatar asked Jul 17 '19 10:07

Sandip Nag


2 Answers

Assign unique keys to your <Swipeable>s.

This will fix your issue of items sharing the opened state when another item is removed.

<Swipeable
  key={someUniqueKey}
  ...
>
  ...
</Swipeable>

like image 142
Alexander Sandberg Avatar answered Oct 24 '22 16:10

Alexander Sandberg


I have just encountered the same issue and tried to solve it using their documentation but didn't find any luck. Here's a workaround I coded to escape it.

<Swipeable
        overshootRight={false}
        renderRightActions={(progress, dragX) => (
            <RightActions progress={progress} dragX={dragX} onPress={() => {
                styles.rightActionStyle.display ='none';
                onRightPress(index);
                styles.rightActionStyle.display ='flex';
            }}/>
        )}
    >... //code continues

'Right actions' is just the Swipeable component I am showing when a user swipes:

    const RightActions = ({dragX, onPress}) => {
    const scale = dragX.interpolate({
        inputRange: [-100, 0],
        outputRange: [1, 0],
        extrapolate: 'clamp',
    });
    return (
        <TouchableOpacity onPress={onPress}>
            <View style={rightActionStyle}>
                <Animated.Text style={[actionTextStyle, {transform: [{scale}]}]}>
                    Delete
                </Animated.Text>
            </View>
        </TouchableOpacity>
    );
};

I am making use of

styles.rightActionStyle.display ='none';

and when action is completed I bring the component back.

styles.rightActionStyle.display ='flex';

Just in case if you are interested, the styles are:

   rightActionStyle: {
        backgroundColor: '#d41359',
        justifyContent: 'center',
        flex: 1,
        alignItems: 'flex-end',
    },

It is a temporary solution. I will be glad if somebody shows how to do it better.

like image 42
Erik Rybalkin Avatar answered Oct 24 '22 16:10

Erik Rybalkin