反应本机:返回android硬件返回按钮按下

反应本机:返回android硬件返回按钮按下,android,reactjs,webview,react-native,Android,Reactjs,Webview,React Native,我正在尝试添加返回webview时,android backbutton被按下,我仍然无法使其工作 这是我的代码: <WebView ref={WEBVIEW_REF} source={source} domStorageEnabled={true} onNavigationStateChange={this.onNavigationStateChange} /> componentDidMount() { BackAndroid.addEv

我正在尝试添加返回webview时,android backbutton被按下,我仍然无法使其工作

这是我的代码:

<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,
    });
};

componentDidMount(){
BackAndroid.addEventListener('hardwareBackPress',function(){
if(this.state.backButtonEnabled){
this.refs[WEBVIEW\u REF].goBack();
返回true;
}
});
};
onNavigationStateChange=(navState)=>{
这是我的国家({
backButtonEnabled:navState.canGoBack,
});
};
通过上面的代码,我得到的错误是undefined不是this.state.backButtonEnabled(在状态中设置)的对象

Than我只是想看看goBack是否有效,所以我删除了if语句,并且得到了错误undefined不是一个对象this.refs[WEBVIEW\u REF]

这方面的最佳解决方案是什么

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) 绑定处理程序2)不要忘记在卸载时重新安装Listener

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

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; }}
      />
    );
  }
}
import React,{Component}来自'React';
进口{
后台处理程序,
平台,
网络视图,
}从“反应本机”;
类ExampleWebView扩展组件{
网络视图={
坎戈巴克:错,
ref:null,
}
onAndroidBackPress=()=>{
if(this.webView.canGoBack&&this.webView.ref){
this.webView.ref.goBack();
返回true;
}
返回false;
}
组件willmount(){
如果(Platform.OS==='android'){
BackHandler.addEventListener('hardwareBackPress',this.onAndroidBackPress);
}
}
组件将卸载(){
如果(Platform.OS==='android'){
removeEventListener('hardwareBackPress');
}
}
render(){
返回(
{this.webView.ref=webView;}}
onNavigationStateChange={(navState)=>{this.webView.canGoBack=navState.canGoBack;}}
/>
);
}
}

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

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

 }
}
import React,{Component}来自'React';
进口{
后台处理程序,
网络视图,
}从“反应本机”;
导出默认类应用程序扩展组件{
建造师(道具){
超级(道具);
this.WEBVIEW_REF=React.createRef();
}
componentDidMount(){
BackHandler.addEventListener('hardwareBackPress',this.handleBackButton);
}
组件将卸载(){
BackHandler.removeEventListener('hardwareBackPress',this.handleBackButton');
}
把手按钮=()=>{
this.WEBVIEW_REF.current.goBack();
返回true;
}
onNavigationStateChange(导航状态){
这是我的国家({
canGoBack:navState.canGoBack
});
}
render(){
返回(
)
}
}

这里有一个使用Typescript和
useRef
useffect
钩子的解决方案

我没有使用
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}
    />
  )
}
import React,{useffect,useRef}来自“React”;
从“react native”导入{BackHandler};
从“react native WebView”导入WebView;
constWebViewWrapper=():JSX.Element=>{
const webview=useRef(null);
常量onAndroidBackPress=():布尔=>{
if(webview.current){
webview.current.goBack();
返回true;//防止默认行为(退出应用程序)
}
返回false;
};
useEffect(():(()=>void)=>{
BackHandler.addEventListener('hardwareBackPress',onAndroidBackPress);
return():void=>{
BackHandler.removeEventListener('hardwareBackPress',onAndroidBackPress);
};
},[]);//永远不要重新运行此效果
返回(
)
}

如果在react native中使用webview,则默认情况下,按下手机的后退按钮时退出应用程序。如果要在按下后退按钮时转到上一页,则需要实现react native webview的“goback”功能


您可以查看本文的部分。

如果您正在寻找
功能组件
解决方案

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

import React,{useState,useffect,useRef}来自“React”
从“react native”导入{BackHandler,Platform}
从“反应导航”导入{SafeAreaView}
从“react native WebView”导入{WebView}
const Webview=()=>{
const webView=useRef(null);
const[canGoBack,setCanGoBack]=useState(false);
useffect(()=>{
如果(Platform.OS==='android'){
BackHandler.addEventListener('hardwareBackPress',HandleBackPress);
return()=>{
BackHandler.removeEventListener('hardwareBackPress',HandleBackPress');
}
}
},[]);//仅初始化一次
const HandleBackPressed=()=>{
if(webView.current){
webView.current.goBack();
返回true;//防止默认行为(退出应用程序)
}
返回false;
}
返回(
setCanGoBack(navState.canGoBack)}
/>
)
}
导出默认Webview;

如果在render方法中抛出backandroid事件侦听器,该怎么办?我收到了相同的错误。我在5分钟前设法修复了它,事实上我也是这样做的:)仍然感谢您的帮助,我相信这也会帮助其他开发人员!BackAndroid将被弃用,最好使用@RamRovi answered这样的BackHandler这是一个全面的解决方案。也许你应该创建一个要点?Getting error-TypeError:TypeError:undefined不是一个对象(计算“\u this2.webView.ref=webView”)需要在androidbackpress上绑定
我想?@Crisfole如果你像我在这里的示例中那样使用箭头函数,就不会了。我很确定会增加一些复杂性,特别是在事件绑定方面。不过我可能错了。请不要使用状态来维护canGoBack,因为更改状态会导致重新渲染,请使用refsHey。这正在工作,但在应用程序中,我们无法在按下backbutton时退出,就像在家中按下backbutton一样,因此应该退出,但不退出a
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;