Re-usable한 Wrapper 컴포넌트 제작
GestureContainer.tsx
import React from 'react';
import GestureRecognizer from 'react-native-swipe-gestures';
import {GestureContainerProps} from './types';
export default function GestureContainer({
  children,
  onSwipeUp = gestureState => console.log('state : ', gestureState),
  onSwipeDown = gestureState => console.log('state : ', gestureState),
  onSwipeLeft = gestureState => console.log('state : ', gestureState),
  onSwipeRight = gestureState => console.log('state : ', gestureState),
  velocityThreshold = 0.3,
  directionalOffsetThreshold = 80,
}: GestureContainerProps) {
  //
  const config = {
    velocityThreshold,
    directionalOffsetThreshold,
  };
  return (
    <GestureRecognizer
      onSwipeUp={state => onSwipeUp(state)}
      onSwipeDown={state => onSwipeDown(state)}
      onSwipeLeft={state => onSwipeLeft(state)}
      onSwipeRight={state => onSwipeRight(state)}
      config={config}
      style={[]}>
      {children}
    </GestureRecognizer>
  );
}
types.ts
import {ReactElement} from 'react';
import {PanResponderGestureState} from 'react-native';
export type SwipeDirections =
  | 'SWIPE_UP'
  | 'SWIPE_DOWN'
  | 'SWIPE_LEFT'
  | 'SWIPE_RIGHT';
export type GestureContainerProps = {
  children: ReactElement;
  onSwipeUp?: (gestureState?: PanResponderGestureState) => void;
  onSwipeDown?: (gestureState?: PanResponderGestureState) => void;
  onSwipeLeft?: (gestureState?: PanResponderGestureState) => void;
  onSwipeRight?: (gestureState?: PanResponderGestureState) => void;
  velocityThreshold?: number;
  directionalOffsetThreshold?: number;
};
export type GestureHandler = (gestureState: PanResponderGestureState) => void;
 
커스텀 wrapper 컴포넌트 활용 예시
GestureExm.tsx
import React, {useState} from 'react';
import {View, Text, StyleSheet, Image, Pressable} from 'react-native';
import * as Animatable from 'react-native-animatable';
import GestureContainer from './GestureContainer';
const summary = require('../images/Summary.png');
const editImg = require('../images/Edit.png');
const deleteImg = require('../images/Delete.png');
export default function GestureExm() {
  const [isLeft, setIsLeft] = useState(false);
  const onLeft = () => {
    setIsLeft(true);
    console.log('left');
  };
  const onRight = () => {
    setIsLeft(false);
    console.log('right');
  };
  const onEdit = () => {
    console.log('수정 누름');
  };
  const onDelete = () => {
    console.log('삭제 누름');
  };
  return (
    <GestureContainer onSwipeLeft={onLeft} onSwipeRight={onRight}>
      <View style={{flexDirection: 'row', width: '100%', padding: 10}}>
        <View style={[styles.summary, isLeft && styles.left]}>
          <Image source={summary} />
        </View>
        {isLeft && (
          <>
            <Animatable.View
              animation="fadeInLeft"
              duration={500}
              style={{zIndex: 1}}>
              <Pressable style={styles.edit} onPress={onEdit}>
                <Image source={editImg} />
                <Text style={styles.buttonText}>수정</Text>
              </Pressable>
            </Animatable.View>
            <Animatable.View
              animation="fadeInLeft"
              duration={500}
              delay={100}
              style={{zIndex: 0}}>
              <Pressable style={styles.delete} onPress={onDelete}>
                <Image source={deleteImg} />
                <Text style={styles.buttonText}>삭제</Text>
              </Pressable>
            </Animatable.View>
          </>
        )}
      </View>
    </GestureContainer>
  );
}
const styles = StyleSheet.create({
  summary: {
    zIndex: 3,
    backgroundColor: 'white',
    borderRadius: 10,
    overflow: 'hidden',
  },
  edit: {
    backgroundColor: '#A8A7B5',
    marginLeft: -8,
    zIndex: 1,
    padding: 10,
    paddingLeft: 15,
    borderTopRightRadius: 10,
    borderBottomRightRadius: 10,
    justifyContent: 'center',
  },
  delete: {
    backgroundColor: '#E00C3E',
    marginLeft: -8,
    zIndex: 0,
    padding: 10,
    paddingLeft: 15,
    borderTopRightRadius: 10,
    borderBottomRightRadius: 10,
    justifyContent: 'center',
  },
  left: {marginLeft: -40},
  buttonText: {color: 'white', fontSize: 14, fontWeight: '600', marginTop: 6},
});