react-native webView 안드로이드에서 뒤로가기 제어하기

김용희·2024년 4월 11일

[project] Art Friendly

목록 보기
8/14

리액트 네이티브 웹뷰를 사용하여 하이브리드 앱 서비스를 제작하고 있습니다. 처음 리액트 네이티브를 사용하여 웹뷰를 제작하고 있어 사소한 기능 하나도 찾아보면서 구현 중입니다.

웹뷰를 구현하는데 있어서 중요한 점은 아마도 'react-native와 웹뷰 사이를 어떻게 부드럽게 연결할 수 있는가' 같습니다. 그 대상이 사용자가 될 수도 있고, 개발자가 될 수도 있습니다.

분명 앱에 웹 사이트를 띄우긴 하지만 그것만으론 부족하며 앱의 기능들을 최소한으로 가져오되 앱으로서의 역할을 충분히 할 수 있을 때 하이브리드 앱이라고 할 수 있는 것 같습니다.


웹뷰에서 안드로이드 뒤로가기 제어하기

구현 원리

  • 웹뷰 내에서 모바일 하드웨어 뒤로가기 버튼을 누를 경우 앱이 나가지게 됩니다. 웹뷰 내에서 네비게이션으로 이동 하더라도 웹뷰 자체를 하나의 페이지로 인식하고 뒤로가기를 누를 경우 앱 밖으로 나가는 것입니다.
  • react-native 내장 기능인 BackHandler와 웹뷰 속성인 onNavigationStateChange을 사용하여 모바일의 하드웨어 뒤로가기 버튼으로도 웹뷰 내에서 뒤로가기가 가능하도록 하였습니다.
  • 앱 메인 화면에서 뒤로가기를 누를 경우 안내창을 통해 앱을 나갈건지 확인한 후 나가도록 하는 기능과, 앱 로딩 중에 뒤로가기를 누를 경우 앱에서 나갈 수 있는 추가적인 기능까지 구현하였습니다.
BackHandler :  하드웨어 뒤로 가기 버튼이나 Android 기기의 뒤로 가기 제스처에 대한 이벤트를 처리하는 컴포넌트
onNavigationStateChange : 네비게이션 상태가 변경될 때 호출되는 이벤트 핸들러

구현 내용

1. ref, useState 설정

const WebViewcontainer = () => {
  const webViewRef = useRef<WebView>(null);
  const [navState, setNavState] = useState({
    url: '',
    canGoBack: false,
  });


  return (
    <WebView
      ref={webViewRef}
      source={{uri: 'your url'}}
    />
  );
};
  • 웹뷰의 ref와 useState로 네비게이션 상태를 설정합니다.
  • url을 설정하는 이유는 추가 기능인 메인화면에서 뒤로가기 시 종료를 위해 설정해두었습니다.

2. onNavigationStateChange 설정

interface navType {
  url: string;
  canGoBack: boolean;
}

const WebViewcontainer = () => {
  const webViewRef = useRef<WebView>(null);
  const [navState, setNavState] = useState({
    url: '',
    canGoBack: false,
  });

  return (
    <WebView
      ref={webViewRef}
      source={{uri: 'your url'}}
      onNavigationStateChange={(nav: navType) => {
        setNavState({url: nav.url, canGoBack: nav.canGoBack});
      }}
    />
  );
};
  • NavigationStateChange에 상태를 연결하고 네비게이션 변화 감지 시 상태를 변경할 수 있도록 합니다.

3. close 함수 구현

import {Alert, BackHandler} from 'react-native';

function close() {
  Alert.alert('종료하시겠어요?', '확인을 누르면 종료합니다.', [
    {
      text: '취소',
      onPress: () => {},
      style: 'cancel',
    },
    {text: '확인', onPress: () => BackHandler.exitApp()},
  ]);
}

export default close;
  • 메인화면에서 뒤로가기 시 안내창을 띄우는 close 함수를 만듭니다.

4. handleBackButton 함수 구현

interface navType {
  url: string;
  canGoBack: boolean;
}

const WebViewcontainer = () => {
  const webViewRef = useRef<WebView>(null);
  const [navState, setNavState] = useState({
    url: '',
    canGoBack: false,
  });
  
  useEffect(() => {
    const handleBackButton = () => {
      if (navState.canGoBack) {
        if (navState.url === 'your url') {
          close();
        } else {
          webViewRef.current?.goBack();
        }
      } else {
        close();
      }

      return true;
    };
  }, [navState]);

  return (
    <WebView
      ref={webViewRef}
      source={{uri: 'your url'}}
      onNavigationStateChange={(nav: navType) => {
        setNavState({url: nav.url, canGoBack: nav.canGoBack});
      }}
    />
  );
};
  • useEffect 내부 handleBackButton 함수에 뒤로가기가 가능할 때 뒤로갈 수 있도록 조건문을 작성합니다.
  • url이 메인 페이지일 경우 안내창을 띄워 앱 밖으로 나갈 수 있도록 합니다.

5. BackHandler에 이벤트리스너 등록

interface navType {
  url: string;
  canGoBack: boolean;
}

const WebViewcontainer = () => {
  const webViewRef = useRef<WebView>(null);
  const [navState, setNavState] = useState({
    url: '',
    canGoBack: false,
  });
  
  useEffect(() => {
    const handleBackButton = () => {
      if (navState.canGoBack) {
        if (navState.url === 'your url') {
          close();
        } else {
          webViewRef.current?.goBack();
        }
      } else {
        close();
      }

      return true;
    };
    
    BackHandler.addEventListener('hardwareBackPress', handleBackButton);

    return () => {
      BackHandler.removeEventListener('hardwareBackPress', handleBackButton);
    };
  }, [navState]);

  return (
    <WebView
      ref={webViewRef}
      source={{uri: 'your url'}}
      onNavigationStateChange={(nav: navType) => {
        setNavState({url: nav.url, canGoBack: nav.canGoBack});
      }}
    />
  );
};
  • BackHandler 컴포넌트에 이벤트로 handleBackButton 함수를 등록하여 하드웨어 뒤로가기 시 설정한 함수가 동작될 수 있도록 설정합니다.
  • 언마운트 시 메모리 누수 방지를 위하여 이벤트를 제거합니다.

완성 화면

0개의 댓글