我试图在按下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,
});
};
使用上面的代码我得到错误undefined不是一个对象this.state.backButtonEnabled(在状态中设置)。
我只是想看看goBack是否有效,所以我删除了if语句而不是我得到错误undefined不是对象this.refs [WEBVIEW_REF]。
最佳解决方案是什么?
答案 0 :(得分:15)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_home"
android:icon="@drawable/ic_dashboard"
android:title="Home" />
</group>
<item android:title="Information">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_the_wetlands"
android:icon="@drawable/ic_event"
android:title="The Wetlands" />
<item
android:id="@+id/nav_the_mistbelt_forests"
android:icon="@drawable/ic_event"
android:title="The Mistbelt Forests" />
<item
android:id="@+id/nav_the_grasslands"
android:icon="@drawable/ic_event"
android:title="The Grasslands" />
</group>
</item>
<item android:title="Quick Go To">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_accommodation"
android:icon="@drawable/ic_event"
android:title="Accommodation" />
<item
android:id="@+id/nav_cuisine"
android:icon="@drawable/ic_forum"
android:title="Cuisine" />
<item
android:id="@+id/nav_leisure_activites"
android:icon="@drawable/ic_forum"
android:title="Leisure & Activites" />
<item
android:id="@+id/nav_agri_tourism"
android:icon="@drawable/ic_forum"
android:title="Agri-tourism" />
<item
android:id="@+id/nav_education"
android:icon="@drawable/ic_forum"
android:title="Education" />
<item
android:id="@+id/nav_arts_crafts_decor"
android:icon="@drawable/ic_forum"
android:title="Arts, Crafts & DeCor" />
<item
android:id="@+id/nav_selective_shopping"
android:icon="@drawable/ic_forum"
android:title="Selective Shopping" />
<item
android:id="@+id/nav_for_children"
android:icon="@drawable/ic_forum"
android:title="For Children" />
</group>
</item>
<item android:title="Midlands Animals">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_midlands_birding_checklist"
android:icon="@drawable/ic_dashboard"
android:title="Midlands Birding Checklist" />
<item
android:id="@+id/nav_midlands_mammals_checklist"
android:icon="@drawable/ic_dashboard"
android:title="Midlands Mammals Checklist" />
</group>
</item>
</menu>
1)绑定你的处理程序2)不要忘记在unmount上删除removeListener。
答案 1 :(得分:13)
想要添加一个完整的示例以防万一:
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; }}
/>
);
}
}
答案 2 :(得分:1)
这是使用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}
/>
)
}
答案 3 :(得分:1)
如果您正在寻找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;
答案 4 :(得分:0)
这可能会帮助某人,因为上述解决方案无法解决我的问题。...
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)}
/>
)
}
}
答案 5 :(得分:0)
如果在React Native中使用Webview,则默认情况下按下移动设备的后退按钮时应用退出。如果要在按返回按钮时转到上一页,则需要实现react-native webview的“ goback”功能。
您可以看到本文的 Step 5 : Handle Mobile Back Button 部分。
答案 6 :(得分:0)
添加到@Nisharg Shah 答案。对于 onNavigationStateChange
道具,添加以下行
onNavigationStateChange={navState => {webView.current.canGoBack = navState.canGoBack}}
并在 HandleBackPressed
方法中检查是否 webView.current.canGoBack
然后 webView.current.goBack();
else return false
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.canGoBack) {
webView.current.goBack();
return true; // PREVENT DEFAULT BEHAVIOUR (EXITING THE APP)
}
return false;
}
return (
<SafeAreaView>
<WebView
ref={webView}
source={{
uri: "<YOUR_URL>"
}}
onNavigationStateChange={navState => {webView.current.canGoBack = navState.canGoBack}} ->> This line is important
/>
</SafeAreaView>
)
}
export default Webview;