React-Native: Go back on android hardware back button pressed

前端 未结 6 2167
悲&欢浪女
悲&欢浪女 2021-02-05 06:14

I am trying to add going back on webview when the android backbutton was pressed and I still couldn\'t manage to make it work.

This is my code:



        
相关标签:
6条回答
  • 2021-02-05 06:49

    Wanted to add a full example in case it helps anyone:

    import React, { Component } from 'react';
    import {
      BackHandler,
      Platform,
      WebView,
    } from 'react-native';
    
    class ExampleWebView extends Component {
      webView = {
        canGoBack: false,
        ref: null,
      }
    
      onAndroidBackPress = () => {
        if (this.webView.canGoBack && this.webView.ref) {
          this.webView.ref.goBack();
          return true;
        }
        return false;
      }
    
      componentWillMount() {
        if (Platform.OS === 'android') {
          BackHandler.addEventListener('hardwareBackPress', this.onAndroidBackPress);
        }
      }
    
      componentWillUnmount() {
        if (Platform.OS === 'android') {
          BackHandler.removeEventListener('hardwareBackPress');
        }
      }
    
      render() {
        return (
          <WebView
            source={{ uri: "https://www.google.com" }}
            ref={(webView) => { this.webView.ref = webView; }}
            onNavigationStateChange={(navState) => { this.webView.canGoBack = navState.canGoBack; }}
          />
        );
      }
    }
    
    0 讨论(0)
  • 2021-02-05 06:53

    In case of webview in react native, app exit when pressing the back button of mobile by default. If you want to go the previous page when pressing the back button then you need to implement the "goback" function of react-native webview.

    You can see the Step 5 : Handle Mobile Back Button section of this article.

    0 讨论(0)
  • 2021-02-05 07:09
    class MyComponent extends Component {
        state = {};
        componentDidMount(){
             BackHandler.addEventListener('hardwareBackPress', this.backHandler);
        }
        componentWillUnmount(){
             BackHandler.removeEventListener('hardwareBackPress', this.backHandler);
        }
        backHandler = () => {
            if(this.state.backButtonEnabled) {
                this.refs[WEBVIEW_REF].goBack();
                return true;
            }
        }
    }
    

    1) Bind your handler 2) Do not forget to removeListener on unmount.

    0 讨论(0)
  • 2021-02-05 07:09

    Here's a solution with Typescript and useRef and useEffect hooks.

    I didn't use canGoBack, but it seems to work regardless.

    import React, { useEffect, useRef } from 'react';
    import { BackHandler } from 'react-native';
    import WebView from 'react-native-webview';
    
    const WebViewWrapper = (): JSX.Element => {
      const webview = useRef<WebView>(null);
      const onAndroidBackPress = (): boolean => {
        if (webview.current) {
          webview.current.goBack();
          return true; // prevent default behavior (exit app)
        }
        return false;
      };
      useEffect((): (() => void) => {
        BackHandler.addEventListener('hardwareBackPress', onAndroidBackPress);
        return (): void => {
          BackHandler.removeEventListener('hardwareBackPress', onAndroidBackPress);
        };
      }, []); // Never re-run this effect
      return (
        <WebView
          source={{ uri: 'https://stackoverflow.com' }}
          ref={webview}
        />
      )
    }
    
    0 讨论(0)
  • 2021-02-05 07:11

    If you are looking for a functional component solution.

    Note: canGoBack state is not required for performing back operation, it's just to save the current state, you can safely remove it if you want

    import React, { useState, useEffect, useRef } from "react"
    import { BackHandler, Platform } from "react-native"
    import { SafeAreaView } from "react-navigation"
    import { WebView } from "react-native-webview"
    
    const Webview = () => {
      const webView = useRef(null);
      const [canGoBack, setCanGoBack] = useState(false);
    
      useEffect(() => {
        if (Platform.OS === 'android') {
          BackHandler.addEventListener('hardwareBackPress', HandleBackPressed);
    
          return () => {
            BackHandler.removeEventListener('hardwareBackPress', HandleBackPressed);
          }
        }
      }, []); // INITIALIZE ONLY ONCE
    
      const HandleBackPressed = () => {
        if (webView.current) {
          webView.current.goBack();
          return true; // PREVENT DEFAULT BEHAVIOUR (EXITING THE APP)
        }
        return false;
      }
    
      return (
        <SafeAreaView>
          <WebView
            ref={webView}
            source={{
              uri: "<YOUR_URL>"
            }}
            onNavigationStateChange={navState => setCanGoBack(navState.canGoBack)}
          />
        </SafeAreaView>
      )
    }
    
    export default Webview;
    
    0 讨论(0)
  • 2021-02-05 07:12

    This might help someone as the above solutions didn't solve my problem....

    import React, { Component } from 'react';
    import {
      BackHandler,
      WebView,
    } from 'react-native';
    
    export default class App extends Component {
    
    constructor(props) {
        super(props);
        this.WEBVIEW_REF = React.createRef();
    }
    
    componentDidMount() {
        BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
    }
    
    componentWillUnmount() {
      BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
    }
    
    handleBackButton = ()=>{
       this.WEBVIEW_REF.current.goBack();
       return true;
    }
    
    onNavigationStateChange(navState) {
      this.setState({
        canGoBack: navState.canGoBack
      });
    }
    
    render(){
       return (
        <WebView
            source={{ uri: "https://www.cbt.ng" }}
            ref={this.WEBVIEW_REF}
            onNavigationStateChange={this.onNavigationStateChange.bind(this)}
         />
        )
    
     }
    }
    
    0 讨论(0)
提交回复
热议问题