React-Native:按下Android硬件后退按钮

Nin*_*yHH 15 android webview reactjs react-native

我试图在按下Android后退按钮时添加回webview,我仍然无法使其工作.

这是我的代码:

<WebView
    ref={WEBVIEW_REF}
    source={source}
    domStorageEnabled={true}
    onNavigationStateChange={this.onNavigationStateChange}
/>

componentDidMount() {
    BackAndroid.addEventListener('hardwareBackPress', function() {
        if(this.state.backButtonEnabled) {
            this.refs[WEBVIEW_REF].goBack();
            return true;
        }
    });
};

onNavigationStateChange = (navState) => {
    this.setState({
        backButtonEnabled: navState.canGoBack,
    });
};
Run Code Online (Sandbox Code Playgroud)

使用上面的代码我得到错误undefined不是一个对象this.state.backButtonEnabled(在状态中设置).

比我只是想看看goBack是否有效,所以我删除了if语句而不是我得到错误undefined不是一个对象this.refs [WEBVIEW_REF].

什么是最好的解决方案?

Ram*_*ovi 22

想要添加一个完整的例子,以防它帮助任何人:

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; }}
      />
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个全面的解决方案。您应该创建要点吗? (2认同)
  • 获取错误 - TypeError: TypeError: undefined is not an object (evaluating '_this2.webView.ref = webView') (2认同)

Yoz*_*ozi 21

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

1)绑定你的处理程序2)不要忘记卸载时删除Listener.

  • 我确实在 5 分钟前修复了它,这实际上也是我所做的:)仍然感谢您的帮助,我相信也会帮助其他开发人员! (2认同)
  • BackAndroid 将被弃用最好像@RamRovi 一样使用 BackHandler 回答 (2认同)

Aar*_*ron 10

这是一个带有打字稿useRefuseEffect钩子的解决方案。

我没有使用canGoBack,但无论如何它似乎都有效。

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}
    />
  )
}
Run Code Online (Sandbox Code Playgroud)


Pet*_*ses 9

这可能对某人有所帮助,因为上述解决方案并没有解决我的问题......

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)}
     />
    )

 }
}
Run Code Online (Sandbox Code Playgroud)


Nis*_*hah 5

如果您正在寻找functional component解决方案。

注意:canGoBack 状态不是执行返回操作所必需的,它只是为了保存当前状态,如果需要,您可以安全地删除它

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;
Run Code Online (Sandbox Code Playgroud)