web-dev-qa-db-ja.com

React-Native:戻るAndroidハードウェアの戻るボタンが押された

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

上記のコードでは、未定義のエラーはオブジェクトthis.state.backButtonEnabled(状態に設定されている)ではありません。

GoBackが機能するかどうかを確認したかったので、ifステートメントを削除しましたが、未定義のエラーがオブジェクトthis.refs [WEBVIEW_REF]ではありませんでした。

これに最適なソリューションは何ですか?

17
NinetyHH
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)アンマウント時にremoveListenerを忘れないでください。

23
Yozi

誰かを助けるために完全な例を追加したかった:

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; }}
      />
    );
  }
}
25
RamRovi

上記の解決策は私の問題を解決しなかったので、これは誰かを助けるかもしれません...

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

 }
}
4
Peter Moses

TypeScriptとuseRefおよびuseEffectフックを使用したソリューションを次に示します。

私は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}
    />
  )
}
2
Aaron