Search code examples
androidreact-nativeexporeact-native-webview

react-native webview in Expo App shows 'about:blank' on Android before exiting the APP with BackHandler


Good day everyone,

I have a problem with an App that gives me some headaches for couple days. The App consists of a WebView containing a PHP WebShop and a bar-code scanner. So far everything was working as expected.

For better Navigation on Android I wanted to use the HardwareBackButton to go back in the WebView History. This also works well but has a major flaw. I want the back button to go back until it cant go back anymore and instead it should exit the App. Now to the actual problem: the last Page url is 'about:blank' and results in a blank screen. From here the canGoBack state is false and the App exits as expected but if you open the App again its still in the 'about:blank' state. My first workaround was to add this.WEBVIEW_REF.current.goForward(); before BackHandler.exitApp;. This helps to get the App back in a navigateable state after exiting but i would like to completely get rid of the blank screen.

I Hope the code below is enough to understand what i wanted to achive:

componentDidMount() {
    BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}

componentWillUnmount() {
    BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
  }

handleBackButton = () => {
    if (this.state.canGoBack) {
      this.WEBVIEW_REF.current.goBack();
      return true;
    }else{
      this.WEBVIEW_REF.current.goForward();
      BackHandler.exitApp;
    };
  }

render() {
    <View style={styles.container}>
        <CustomStatusBar backgroundColor="#ee7203" barStyle="light-content" />
          <View style={styles.main}>
            <WebView
              onLoad={() => this.hideSpinner()}
              cacheEnabled={false}
              source={{
                uri: this.state.webshopURL,
              }}
              ref={this.WEBVIEW_REF}              
              onNavigationStateChange={(navState) => {
                console.log(navState);
                this.setState({
                  canGoBack: navState.canGoBack,
                  currentUrl: navState.url,
                });
              }}
              allowsBackForwardNavigationGestures={true}
              incognito={true}
              onMessage={(event) => {
                this.handleWebMassage(event.nativeEvent.data);
              }}
            />
            {this.state.scannerOpen === true && (
              <View style={styles.barcodeScannerContainer}>
                <BarCodeScanner
                  onBarCodeScanned={
                    this.state.scanned ? undefined : handleBarCodeScanned
                  }
                  style={[StyleSheet.absoluteFill, styles.barcodeScanner]}
                >
                  <BarcodeMask edgeColor="#62B1F6" showAnimatedLine={false}/>
                    <TouchableOpacity
                      onPress={() => this.closeScanner()}
                      style={styles.cancel}
                      light
                    >
                      <Icon name="close" color="#58585a" />
                    </TouchableOpacity>
                  </BarCodeScanner>
              </View>
            )}
          </View>

        {this.state.showSplash === true && (
          <View style={styles.splash}>
            <Animated.Image
              onLoad={this.onLoad}
              {...this.props}
              style={[
                {
                  opacity: this.state.opacity,
                  transform: [
                    {
                      scale: this.state.opacity.interpolate({
                        inputRange: [0, 1],
                        outputRange: [0.85, 1],
                      }),
                    },
                  ],
                },
                this.props.style,
              ]}
              style={styles.logo}
              source={logo}
              resizeMode={"contain"}
            />
          </View>
        )}
      </View>

Solution

  • I found a workaround for the Problem. The App has a SplashScreen on start and I simply set the state of canGoBack to false and am clearing the WebViews history when the SplashScreen closes.

    this.sleep(5000).then(() => {
      this.setState({
        showSplash: false,
        canGoBack: false,
      });
      this.WEBVIEW_REF.current.clearHistory();
    });