프론트엔드

[React Native] 웹뷰내에서 페이지 로딩값 구하기

임고미 2022. 10. 21. 14:11
728x90
300x250

리액트 네이티브 웹뷰내에서 페이지간 이동할때 로딩값을 확인하고 싶었으나,.

WebviewEvent에서 보여주는 loading은 웹뷰가 처음 실행될때만 바뀌고 그 이후에는 계속 변화가 없는 의미없는 값이었다.

해당 값으로는 웹뷰가 처음으로 로딩될때 어떤 컴포넌트를 보여줄지를 컨트롤하는데 사용되고 있었다.

그래서 페이지간 로딩값을 어떻게 구할 수 있을지 고민하다 한가지 얻은 답은 웹뷰의

injectedJavaScript을 이용하는 것이었다.

 

injectedJavaScript은 웹뷰내에서 작동될 JS를 적어줄 수 있는 곳인데, 이곳에 내가 원하는 코드를 삽입함으로써 이문제를 해결할 수 있었다.

 

해결책은 다음과 같았다.

웹뷰 현재 링크(currentUrl)와 NavigationStatechange에서 주는 url(navigationUrl)을 비교하여, 그 값이 같지 않을때가 loading 중 같아질때가 loading 끝난시점으로 잡는것 이다. 

1. navigationUrl 얻기

웹뷰에는 onNavigationStateChange라는 속성을 제공하고 있다. 이것은 웹뷰가 변하기 시작할때, 종료될때 2번 작동하게 되는데 이때 우리는 이동하는 url을 얻을 수 있다.

// navigation이 이동할떄 얻을 수 있는 속성 값
export interface WebViewNativeEvent {
    url: string;
    loading: boolean;
    title: string;
    canGoBack: boolean;
    canGoForward: boolean;
    lockIdentifier: number;
}

 이때 우리는 navigationUrl 을 저장해준다. 

-> 2번 작동하게 되므로, 해당 웹뷰가 replace등을 이유로 url이 변하더라도 최신의 url을 얻을 수 있다.

2. 변화가 완료된 페이지에서 현재 url을 가져온다.

injectedJavaScript에 다음과 같은 코드를 삽입.
 
  window.onpageshow = (e) => {
    window.ReactNativeWebView.postMessage(window.location.href);
  };
 
pageshow는 dom이 그려진 뒤 작동하는것으로, 로딩이 끝났을 응답이 온다. 따라서 로딩이 끝났음을 알여주는 응답으로 파악할 수 있다.
 

처음에는 onload를 사용하였는데,  onload를 사용하고 뒤로가기 버튼을 클릭하였더니 해당 메세지가 오지 않는것을 확인했다.

이유는 캐시때문. 최적화를 위해 한번 다녀온 페이지의 캐시를 남기기 때문에 다시 onload를 하지 않기때문에 캐시를 남기지않는 onpageshow를 사용하여 현재 url을 얻었다.

3. 두값을 저장하여 비교함으로써 로딩이 진행중인지 끝났는지를 파악할 수 있다.

navigationUrl은 바로 변경되고, currentUrl은 load가 완료되고 로드되니 현재 로딩 여부를 구할 수 있다.

4. 이슈

그런데 한가지 이슈를 확인했다.

한 페이지 내에서 섹션별로 id를 주고 a태그를 통해 이동해 다니는 링크에대해서는 대응이 안된다는것.

이 부분은 추후에 수정하여 추가하겠다.

 

728x90
300x250