본문 바로가기
프로그래밍/React-Native <JSX>

[React-Native] 두 Modal을 활용하여 뒷 배경 어둡게 처리하기

by TaeGyeong Lee 2023. 5. 6.

React Native 에서 기본적으로 제공하는 Modal 만을 활용해 Modal 활성화 시 배경을 어둡게 하도록 코드를 작성해 보겠습니다. 대부분의 앱들에서 볼 수 있는 사용자 경험입니다.

 

실행 화면

구현한 실행 화면부터 확인해 보겠습니다.

- 뒷 배경 흐림에 fade 옵션을 준 경우

 

- 뒷 배경 흐림에 none 옵션을 준 경우, 보다 즉각적인 반응을 얻을 수 있습니다. 저라면 이 버전을 사용할 것 같네요.

 

Modal 구현

이를 구현하기 위해 두 가지 Modal을 사용해야 합니다. 하나는 뒷 배경을 어둡게 할 ContainerModal 이고 나머지 하나는 사용자가 집중하게 될 내용을 담을 TestModal 입니다. 

ContainerModal

뒷 배경을 어둡게 처리할 Modal 입니다. 어떻게 어둡게 할 것인지 선호에 따라 animationType 옵션을 주면 됩니다. 어두워지는 정도를 조절하고 싶다면 backgroundColor 값을 조절하면 됩니다.

문득 든 생각인데, ContainerModal 을 재사용가능하기 위해 자식 Modal(여기선 TestModal) 또한 전달받도록 설계하면 좋을 것 같네요.
function ContainerModal({visible, closeModal}: any) {
  return (
    <Modal visible={visible} transparent={true} animationType="fade">
      <View style={{flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.7)'}}></View>
      <TestModal visible={visible} closeModal={closeModal} />
    </Modal>
  );
}

 

TestModal

사용자들에게 어필하고자 하는 내용이 들어간 Modal 입니다.

function TestModal({visible, closeModal}: any) {
  return (
    <Modal visible={visible} transparent={true} animationType="slide">
      <SafeAreaView style={{marginTop: 'auto'}}>
        <View
          style={{
            backgroundColor: '#00ff00',
            paddingTop: 60,
            paddingBottom: 60,
            borderTopEndRadius: 24,
            borderTopStartRadius: 24,
          }}>
          <TouchableOpacity
            onPress={() => {
              closeModal();
            }}>
            <Text
              style={{
                backgroundColor: '#FF0000',
                padding: 10,
                alignSelf: 'center',
              }}>
              Close
            </Text>
          </TouchableOpacity>
        </View>
      </SafeAreaView>
    </Modal>
  );
}

 

전체 소스 코드

RN 0.72.2 에서 정상적으로 실행되는 것을 확인했습니다.

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 */

import React, {useState} from 'react';
import {
  Text,
  View,
  StyleSheet,
  TextInput,
  Modal,
  SafeAreaView,
  TouchableOpacity,
} from 'react-native';

export default function App() {
  const [isModalVisible, setModalVisible] = useState(false);

  return (
    <View style={{}}>
      <SafeAreaView>
        <TouchableOpacity
          onPress={() => {
            setModalVisible(true);
          }}>
          <Text
            style={{
              backgroundColor: '#00ff00',
              padding: 10,
              alignSelf: 'center',
            }}>
            Click Me
          </Text>
        </TouchableOpacity>
      </SafeAreaView>
      <ContainerModal
        visible={isModalVisible}
        closeModal={() => {
          setModalVisible(false);
        }}
      />
    </View>
  );
}

function TestModal({visible, closeModal}: any) {
  return (
    <Modal visible={visible} transparent={true} animationType="slide">
      <SafeAreaView style={{marginTop: 'auto'}}>
        <View
          style={{
            backgroundColor: '#00ff00',
            paddingTop: 60,
            paddingBottom: 60,
            borderTopEndRadius: 24,
            borderTopStartRadius: 24,
          }}>
          <TouchableOpacity
            onPress={() => {
              closeModal();
            }}>
            <Text
              style={{
                backgroundColor: '#FF0000',
                padding: 10,
                alignSelf: 'center',
              }}>
              Close
            </Text>
          </TouchableOpacity>
        </View>
      </SafeAreaView>
    </Modal>
  );
}

function ContainerModal({visible, closeModal}: any) {
  return (
    <Modal visible={visible} transparent={true} animationType="none">
      <View style={{flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.7)'}}></View>
      <TestModal visible={visible} closeModal={closeModal} />
    </Modal>
  );
}

 

이 코드는 재사용하기는 어려워 보이네요. ContainerModal 을 재사용가능하게 수정하여 사용하면 좋을 것 같습니다.