더북(TheBook)

15.11.2 삭제 기능 구현하기

이번에는 삭제 기능을 구현해봅시다. 사용자가 실수로 삭제하는 것을 방지하기 위해 삭제 버튼을 눌렀을 때 정말 삭제할지 한번 물어보고 나서 삭제하도록 구현하겠습니다.

이를 구현하기 위해 AskDialog라는 컴포넌트를 만들 텐데, 이 컴포넌트는 추후 댓글 삭제 기능을 구현할 때도 사용합니다. 따라서 재사용성을 고려하여 개발하겠습니다.

components/AskDialog.tsx

import React from 'react';
import {View, StyleSheet, Modal, Text, Pressable} from 'react-native';

export interface AskDialogProps {
  visible: boolean;
  title: string;
  message: string;
  confirmText: string;
  cancelText?: string;
  isDestructive?: boolean;
  onClose(): void;
  onConfirm(): void;
}

function AskDialog({
  visible,
  title,
  message,
  confirmText,
  cancelText = '취소',
  isDestructive,
  onConfirm,
  onClose,
}: AskDialogProps) {
  return (
    <Modal transparent animationType="fade" visible={visible}>
      <View style={styles.block}>
        <View style={styles.whiteBox}>
          <Text style={styles.title}>{title}</Text>
          <Text style={styles.message}>{message}</Text>
            <View style={styles.buttons}>
              <Pressable
                style={({pressed}) => pressed && styles.pressed}
                hitSlop={8}
                onPress={onClose}>
                <Text style={[styles.buttonText, styles.cancelText]}>
                  {cancelText}
                </Text>
              </Pressable>
              <View style={styles.separator} />
              <Pressable
                style={({pressed}) => pressed && styles.pressed}
                hitSlop={8}
                onPress={onConfirm}>
                <Text
                  style={[
                  styles.buttonText,
                  styles.confirmText,
                  isDestructive && styles.destructive,
                ]}>
                {confirmText}
              </Text>
            </Pressable>
          </View>
        </View>
      </View>
    </Modal>
  );
}

const styles = StyleSheet.create({
  block: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.5)',
    alignItems: 'center',
    justifyContent: 'center',
  },
  whiteBox: {
    borderRadius: 4,
    width: 320,
    paddingVertical: 24,
    paddingHorizontal: 24,
    backgroundColor: 'white',
  },
  title: {
    fontSize: 18,
    fontWeight: 'bold',
  },
  message: {
    marginTop: 16,
    marginBottom: 32,
  },
  buttons: {
    flexDirection: 'row',
    justifyContent: 'flex-end',
  },
  buttonText: {
    fontSize: 12,
  },
  cancelText: {
    color: '#454545',
  },
  confirmText: {
    fontWeight: 'bold',
    color: '#2196f3',
  },
  destructive: {
    color: '#f44336',
  },
  pressed: {
    opacity: 0.75,
  },
  separator: {
    width: 16,
  },
});

export default AskDialog;
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.