티스토리 뷰

저희는 현재 보통 WebView에서 onNavigationStateChange 에서 이벤트를 받아서
canGoBack이라는 boolean타입을 받고, state에 저장합니다
Android 백버튼을 누르면 state의 canGoback 을 확인하고, true일시 WebView의 goBack()을 호출하는 방향으로 해결해왔었는데용

backHandlerAction = () => {
  if (this.state.canGoBack) {
  this.webViewRef.current && this.webViewRef.current.goBack()
  } else {
  return false
  }
return true
}

이게 그러니까 CSR로 동작할 때(리액트 라우터나, 넥스트라우터 같은), SPA에서는 보통 location의 이동이 아닌 history.pushState, replaceState를 사용하기 때문에 onNavigationStateChange 이벤트가 일어나지 않게 됩니다.

얼마전에도 Next의 Router.push 할때도 그렇게 동작해서 그 때는 잘 몰라서 Router.push를 location.href =  형식으로 다 바꿔서 억지로 onNavigationStateChange 이벤트가 일어나게 처리했는데용,

성능에도 좋지않고(서버를 한번 더 타니까) 여러모로 불편했습니다.

이번에 통합로그인 작업하면서 통합로그인이 history의 pushState로 동작하고 있는 부분이 많아서 백버튼 처리에 애를 먹었습니다.

관련해서 찾아보니까 https://github.com/react-native-webview/react-native-webview/issues/24 
비슷한 이슈를 겪고 있는 사람들이 있었고,

해당 글 참고하여
WebView의 injectedJavaScript에 아래 코드 집어넣고 pushState 일어날 때마다 postMessage받아서 canGoBack을 true로 바꿔주었습니다.

function wrap(fn) {
  return function wrapper() {
    var res = fn.apply(this, arguments);
    window.ReactNativeWebView.postMessage(
    '{"name": "HISTORY_CHANGE"}'
    );
    return res;
  };
}
history.pushState = wrap(history.pushState);

여기서 좀 더 발전시키면 WebView에서 아예 스택으로 히스토리를 관리해서 replaceState, popState 일어날 때 마다 처리를 해주면, 앞으로 WebView에서 히스토리 처리하는데 좀 더 도움이 될 것 같습니당

댓글