反应本机:返回android硬件返回按钮按下
我正在尝试添加返回webview时,android backbutton被按下,我仍然无法使其工作 这是我的代码:反应本机:返回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
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;