React Native 개발에서 안드로이드 기기의 하드웨어 백 버튼을 관리하는 것은 기초적인 작업입니다.
종종 백 버튼의 동작을 사용자 정의하고 싶어하며, 특히 앱의 실수로 나가는 것을 방지하거나 네비게이션 흐름을 제어하고 싶어합니다.
하나의 전형적인 흐름도를 볼땐, 사용자가 앱을 종료하기 전에 확인 메시지를 표시하는 것입니다.
그러나 이 동작을 특정 화면에서만 활성화되도록 올바르게 구현하려면,
특히 React Navigation과 같은 네비게이션 라이브러리를 사용할 때 미묘한 접근 방식이 필요합니다.
기초 이해하기
React Native의 BackHandler API는 안드로이드 기기에서 하드웨어 백 버튼 누름을 감지하고 처리할 수 있게 해줍니다.
useEffect(() => {
const backAction = () => {
// 백 버튼 누름 처리
return true;
};
const backHandler = BackHandler.addEventListener('hardwareBackPress', backAction);
return () => backHandler.remove();
}, []);
그러나 네비게이션 스택의 일부인 컴포넌트에 이를 추가하면, 의도한 화면이 아니라 앱 전체에 핸들러가 활성화됩니다.
여기서 useFocusEffect가 @react-navigation/native에서 제공하는 훅을 활용하여 우리가 원하는 결과를 찾을 수 있습니다.
useFocusEffect를 사용하여 백 버튼 동작 맞춤 설정하기
useFocusEffect는 화면이 포커스되거나 흐려질 때 효과를 트리거하는 React Navigation에서 제공하는 훅입니다.
import React, { useCallback } from 'react';
import { BackHandler, ToastAndroid } from 'react-native';
import { useFocusEffect } from '@react-navigation/native';
최종 코드 구현
백 버튼 핸들러 설정하기
백 버튼 동작을 제어할 컴포넌트 내에 핸들러 함수를 정의합니다.
이 함수는 토스트 메시지를 표시하고 이중 탭으로 종료 패턴을 처리하는 역할을 합니다.
const MyScreen = () => {
useFocusEffect(
useCallback(() => {
let backPressed = 0;
const backAction = () => {
if (backPressed < 1) {
backPressed++;
ToastAndroid.show(
"한 번 더 '뒤로' 버튼을 누르면 종료됩니다.",
ToastAndroid.SHORT,
);
setTimeout(() => {
backPressed = 0;
}, 2000);
return true;
} else {
BackHandler.exitApp();
}
};
const backHandler = BackHandler.addEventListener('hardwareBackPress', backAction);
return () => backHandler.remove();
}, [])
);
return <></>; // 여러분의 화면/컴포넌트 콘텐츠
};
화면 포커스에 훅 걸기
useFocusEffect를 사용하여 백 버튼 로직을 감싸면, 핸들러가 화면이 포커스될 때만 활성화되도록 할 수 있습니다.
이는 전체적인 백 버튼 처리 문제를 해결해주며, 더 직관적인 사용자 경험을 제공합니다.
결론
React Navigation을 사용하는 React Native 앱에서 화면별로 백 버튼 관리를 효과적으로 구현하면 사용자 네비게이션 제어를 강화하고 의도치 않은 앱 종료를 방지할 수 있습니다. 핵심은 useFocusEffect를 활용하여 사용자 정의 로직이 화면의 포커스 상태와 연결되도록 하는 것입니다.
'ReactNative' 카테고리의 다른 글
[RN] React Native에서 사용자 정의로 직접 캘린더(달력) 구현하기 (3) | 2024.02.27 |
---|---|
RN에서 캘린더 기능 쉽게 추가하기 - React-Native-Calendars 라이브러리 활용 가이드 (0) | 2024.02.26 |
[ReactNative] - rn-fetch-blob OR @react-native-community/cameraroll 사용하여 앱에 파일 저장하기 (2) | 2023.11.03 |
[ReactNative] - rn-fetch-blob 사용시 cycle 이슈 해결방안 (0) | 2023.11.03 |
[ReactNatvie] react-native-image-viewing를 사용하여 이미지 슬라이드안에 동영상도 넣을 수 있을까? (2) | 2023.11.03 |