undefined不是一个函数(评估'_this.webview.goBack()')

时间:2017-11-13 16:02:39

标签: javascript android react-native android-webview

我还是React-Native的新手,我正试图弄清楚当用户点击Android设备上的后退按钮时如何访问我的webview以触发goBack功能。这就是我得到的

constructor(props){
    super(props);
}   

componentDidMount() {
    BackAndroid.addEventListener('hardwareBackPress', this.backHandler);
    this.webview.messagesChannel.on('text', function({...})) //this is working
}

componentWillUnmount() {
    BackAndroid.removeEventListener('hardwareBackPress', this.backHandler);
}

backHandler = () => {
    this.webview.goBack(); //this throws and error
    return true;
}

render() {
    return (
      <View style={styles.parent}>
          <WebView
            userAgent={"mobileapp"}
            source={{uri: url}} style={styles.fullScreen}
            domStorageEnabled={true}
            ref={this._refWebView}
          />
      </View>
    );
}

_refWebView = (webview) => {
    this.webview = webview;
}

我在模拟器上出现以下错误

  

undefined不是一个函数(评估'_this.webview.goBack()')

访问this.webview的正确方法是什么?

谢谢!

2 个答案:

答案 0 :(得分:0)

访问WebView的参考文献没有错。

WebView上的ref回调有问题。 它被多次调用,有时使用ref = null,因此它可能会覆盖先前设置的引用this.webview

要修复(这不应该发生...... 确保在设置之前获得定义的WebView参考

_refWebView = (webview) => {
    if (!webview) {
      return;
    }
    this.webview = webview;
}

答案 1 :(得分:0)

我知道这为时已晚。当我在Webview上寻找后退按钮的解决方案时发现了这个问题,并通过结合以下的一些指南/参考文献并对其非常满意而实现了一个好的解决方案。想我应该与将来希望实现自定义后退按钮行为的任何人分享。

import React from 'react';
import { ScrollView, WebView, View, BackHandler } from 'react-native';

export default class WebScreen extends React.Component {
  static navigationOptions = () => {
    return {
      header: null,
    }
  };

  _didFocusSubscription;
  _willBlurSubscription;

  constructor(props) {
    super(props);
    this.state = { canGoBack: false };
    this._didFocusSubscription = props.navigation.addListener('didFocus', payload =>
    BackHandler.addEventListener('hardwareBackPress', this.onBackButtonPressAndroid));
  }

  componentDidMount() {
    this._willBlurSubscription = this.props.navigation.addListener('willBlur', payload =>
    BackHandler.removeEventListener('hardwareBackPress', this.onBackButtonPressAndroid));
  }

  onBackButtonPressAndroid = () => {
    if (this.state.canGoBack) {
      this.webview.goBack();
      return true;
    } else {
      return false;
    }
  };

  componentWillUnmount() {
    this._didFocusSubscription && this._didFocusSubscription.remove();
    this._willBlurSubscription && this._willBlurSubscription.remove();
  }

  _refWebView = (webview) => {
    this.webview = webview;
  }

  render() {
    return (
      <View style={{ flex: 1 }}>
        <View style={{ height: 20 }} />
        <WebView
          ref={this._refWebView}
          source={{ uri: 'url' }}
          onError={console.error.bind(console, 'error')}
          bounces={false}
          onShouldStartLoadWithRequest={() => true}
          javaScriptEnabledAndroid={true}
          startInLoadingState={true}
          onNavigationStateChange={this.onNavigationStateChange.bind(this)}
          style={{ flex: 1 }}
        />
      </View>
    );
  }

  onNavigationStateChange(navState) {
    this.setState({
      canGoBack: navState.canGoBack
    });
  }
}