1

When I click the hardware button on android the app closes, I want to go back on the previous page,

This is my code

import { StatusBar } from 'expo-status-bar';
import React, { useState } from 'react';
import { ActivityIndicator, Linking, SafeAreaView, StyleSheet, Text, View } from 'react-native';
import { WebView } from 'react-native-webview';

export default function App() {
  const [isLoadong, setLoading] = useState(false);

  return (
    <SafeAreaView style={styles.safeArea}>
      <WebView
          originWhiteList={['*']}
          source={{ uri: 'https://google.com' }}
          style={styles.container } 
          onLoadStart={(syntheticEvent) => {
          setLoading(true);
        }}
        onShouldStartLoadWithRequest={(event)=>{
          if (event.navigationType === 'click') {
            if (!event.url.match(/(google\.com\/*)/) ) {
              Linking.openURL(event.url)
              return false
              }
              return true
          }else{
            return true;
          }
        }}
        onLoadEnd={(syntheticEvent) => {
          setLoading(false);
        }} />
        {isLoadong && (
            <ActivityIndicator
              color="#234356"
              size="large"
              style={styles.loading}
            />
        )}
        </SafeAreaView>
    );
}



const styles = StyleSheet.create({
  safeArea: {
    flex: 1,
    backgroundColor: '#234356'
  },
  loading: {
    position: 'absolute',
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    alignItems: 'center',
    justifyContent: 'center'
  },
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
Peril
  • 1,569
  • 6
  • 25
  • 42

3 Answers3

6

There are built-in goBack() method available in react-native-webview libraries you can use the API method to implement back navigation of webview.

For this, you have to get the reference of react-native-webview component and call method from the reference object.

also, you are able to put the listener on the Android Native Back Button Press event to call the goBack() method of webview.

try the following code...

    import { StatusBar } from 'expo-status-bar';
    import React, { useState, useRef, useEffect } from 'react';
    import { ActivityIndicator, Linking, SafeAreaView, StyleSheet, BackHandler } from 'react-native';
    import { WebView } from 'react-native-webview';

    export default function App() {
        const webViewRef = useRef()
        const [isLoadong, setLoading] = useState(false);

        const handleBackButtonPress = () => {
            try {
                webViewRef.current?.goBack()
            } catch (err) {
                console.log("[handleBackButtonPress] Error : ", err.message)
            }
        }

        useEffect(() => {
            BackHandler.addEventListener("hardwareBackPress", handleBackButtonPress)
            return () => {
                BackHandler.removeEventListener("hardwareBackPress", handleBackButtonPress)
            };
        }, []);
  
        return (
          <SafeAreaView style={styles.safeArea}>
            <WebView
                originWhiteList={['*']}
                source={{ uri: 'https://google.com' }}
                style={styles.container} 
                ref={webViewRef}
                onLoadStart={(syntheticEvent) => {
                    setLoading(true);
                }}
                onShouldStartLoadWithRequest={(event)=>{
                    if (event.navigationType === 'click') {
                        if (!event.url.match(/(google\.com\/*)/) ) {
                            Linking.openURL(event.url)
                            return false
                        }
                        return true
                    }
                    else{
                        return true;
                    }
                }}
                onLoadEnd={(syntheticEvent) => {
                    setLoading(false);
                }}
            />
            {isLoadong && (
                <ActivityIndicator
                color="#234356"
                size="large"
                style={styles.loading}
                />
            )}
            </SafeAreaView>
          );
      }
    const styles = StyleSheet.create({
      safeArea: {
      flex: 1,
      backgroundColor: '#234356'
    },
    loading: {
      position: 'absolute',
      left: 0,
      right: 0,
      top: 0,
      bottom: 0,
      alignItems: 'center',
      justifyContent: 'center'
    },
    container: {
      flex: 1,
      backgroundColor: '#fff',
      alignItems: 'center',
      justifyContent: 'center',
    },
  });
Jignesh Mayani
  • 6,937
  • 1
  • 20
  • 36
1

first add ref for access your webview like that:

 <WebView
    ref={WEBVIEW_REF}

then for access to Hardware Back Button you can use this:

import { BackHandler } from 'react-native';

constructor(props) {
    super(props)
    this.handleBackButtonClick = this.handleBackButtonClick.bind(this);
}

componentWillMount() {
    BackHandler.addEventListener('hardwareBackPress', this.handleBackButtonClick);
}

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

handleBackButtonClick() {
    this.refs[WEBVIEW_REF].goBack();
    return true;
}

in handleBackButtonClick you can do back for webview and add this.refs[WEBVIEW_REF].goBack(); . I Hope that's helpful:)

Meisan Saba
  • 800
  • 2
  • 9
  • 25
1

Here is a simple solution using the magic of React's State.

Hope this helps.

import React, { useRef, useState } from 'react'

export default function Component () {

    // This is used to save the reference of your webview, so you can control it
    const webViewRef = useRef(null);

    // This state saves whether your WebView can go back
    const [webViewcanGoBack, setWebViewcanGoBack] = useState(false);

    const goBack = () => {

        // Getting the webview reference
        const webView = webViewRef.current
        
        if (webViewcanGoBack)
            // Do stuff here if your webview can go back 
        else
            // Do stuff here if your webview can't go back 
    }

    return (        
        <WebView
            source={{ uri: `Your URL` }}
            ref={webViewRef}
            javaScriptEnabled={true}
            onLoadProgress={({ nativeEvent }) => {
                // This function is called everytime your web view loads a page
                // and here we change the state of can go back
                setWebViewcanGoBack(nativeEvent.canGoBack)
            }}
        />
    )
}
Nazim.A
  • 101
  • 1
  • 4