리액트 네이티브 expo 도전기 (1)

JoonPark·2023년 11월 29일
0

리액트 네이티브

목록 보기
1/2
post-thumbnail

서론

리액트에 익숙하다면 리액트 네이티브를 배우는데 진입장벽이 낮다는 말에 회사에서 진행중인 웹 서비스를 웹뷰로 만들어보기로 했다.
앱으로 간편하게 테스트 할 수 있고 배포도 쉬운 expo로 프로젝트를 시작했다.

세팅 시행착오

아쉽게도 회사 컴퓨터는 옛날 버전 윈도우 10, 홈에디션이어서 Hyper-V 기능이 빠져 PC로 앱을 테스트 할 수 없었다. 이를 해결하기 위해서 아래와 같은 과정을 거쳤다.
사실 세팅에만 거의 하루 종일 걸렸지만 매우 짧게 요약하자면 아래와 같다.

  1. Android Studio 설치 및 갤럭시 S23버전으로 가상 테스트 기기 세팅 완료
  2. 윈도우를 최신 버전으로 업데이트하려 했으나 TMP2.0(보안 부팅)이 활성되지 않아 실패
  3. 바이오스에서 보안 부팅을 'Enable' 처리
  4. 윈도우 업데이트 성공
  5. 'Windows 기능 켜기/끄기'에서 'Hyper-V'와 'Windows Hypervisor Platform'을 체크
  6. 프로젝트 내에서 yarn start로 Android Studio를 불러와 테스트 가능

개발 진행

반응형만 잘 되어있으면 웹뷰 구현은 금방이야!

  • 여기까지 하고 테스트 했을 때 의도한 웹뷰는 금방 구현할 수 있었다.
  • 주말 이틀을 꼬박 날렸지만 사실 세팅에 하루, 아래 코드 쓰고 익히는데 하루 걸렸다.
  • 뒤로가기 버튼에 웹뷰 ref를 따로 넣지 않으면 어떤 화면이든 어플이 그냥 종료되어버린다.
  • 상단바 영역을 명시해주지 않으면 상단바를 덮어버리거나, 묻힌다.
  • 여기저기 참고한 내용이 class 형식의 컴포넌트라 아래와 같이 만들게 되었다
    (나는 진심으로 ReactNative 에서는 이런 형식으로 개발하는줄 알았다 😭)
  • 뭐 안드로이드 관련만 세팅해놓은거 아니냐고? 나 iOS 기기가 하나도 없어요...
export default class App extends Component {
  webView = {
    canGoBack: false,
    ref: null,
  };

  onAndroidBackPress = () => {
    if (this.webView.canGoBack && this.webView.ref) {
      this.webView.ref.goBack();
      return true;
    }
    return false;
  };

  componentDidMount() {
    if (Platform.OS === "android") {
      BackHandler.addEventListener(
        "hardwareBackPress",
        this.onAndroidBackPress,
      );
    }
  }

  componentWillUnmount() {
    if (Platform.OS === "android") {
      BackHandler.removeEventListener("hardwareBackPress");
    }
  }
  render() {
    return (
      <View style={{ flex: 1, paddingTop: 18, backgroundColor: "white" }}>
        <StatusBar />
        <WebView
          source={{
            uri: "서비스 url",
          }}
          ref={(webView) => {
            this.webView.ref = webView;
          }}
          onNavigationStateChange={(navState) => {
            this.webView.canGoBack = navState.canGoBack;
          }}
        />
      </View>
    );
  }
}

잠깐, 리액트 훅을 쓰고 싶은데 RN에서 걍 쓰면 된다고?

  • 훅을 쓰고싶어서 방법을 알아보다가 그냥 함수형 컴포넌트로 바꾸면 된다는 사실을 알게 된다
  • DidMount, DidUpdate, WillUnmount 열심히 익혔는데 그냥 useEffect로 해결!
  • 그래서 수정된 코드는 다음과 같다
export default function App() {
  const webViewRef = useRef(null);
  const [canGoBack, setCanGoBack] = useState(false);
  const [showLanding, setShowLanding] = useState(true);

  const onAndroidBackPress = () => {
    if (canGoBack) {
      webViewRef.current.goBack();
      return true;
    }
    return false;
  };

  useEffect(() => {
    if (Platform.OS === "android") {
      BackHandler.addEventListener("hardwareBackPress", onAndroidBackPress);
    }

    return () => {
      if (Platform.OS === "android") {
        BackHandler.removeEventListener(
          "hardwareBackPress",
          onAndroidBackPress,
        );
      }
    };
  }, [canGoBack]);

  const onNavigationStateChange = (navState) => {
    setCanGoBack(navState.canGoBack);
  };

  if (showLanding) {
    return <Landing setShowLanding={setShowLanding} />;
  }

  return (
    <View style={styles.container}>
      <StatusBar />
      <WebView
        source={{ uri: "서비스 url" }}
        ref={webViewRef}
        onNavigationStateChange={onNavigationStateChange}
      />
    </View>
  );
}

결론

내가 익숙한 코드로 바꾸고 나니 한결 맘이 너무 편하다. 이제서야 왜 리액트 개발자가 RN도 학습이 쉬운지 알게 되었다. 아직 안드로이드는 병아리 수준이지만 번듯하게 어플리케이션으로 동작하는 웹뷰를 보니 뭔가 자신감이 생긴다.
어플리케이션 심사 및 배포는 다른 페이지에서 너무 자세히 설명된 글이 많아 생략한다.

차후 공부가 필요한 내용은 다음과 같다

  • 앱 구동 전 랜딩 페이지 생성
  • 코드 푸시로 심사 없이 어플리케이션 서비스 변경
  • 기기 위치 접근 권한을 받아 웹뷰에서 내 위치를 누르면 위치 찾기
profile
FE Developer

0개의 댓글