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]ではありませんでした。
これに最適なソリューションは何ですか?
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を忘れないでください。
誰かを助けるために完全な例を追加したかった:
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 } 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)}
/>
)
}
}
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}
/>
)
}