且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我如何返回 webview?我在 react-native 中使用 react-navigation 包

更新时间:2023-12-03 18:11:28

按照官方 webview 文档,您可以尝试这样做:https://github.com/react-native-community/react-native-webview/blob/master/docs/Guide.md#intercepting-hash-url-changes

Following the official webview documnentation you could try to do this: https://github.com/react-native-community/react-native-webview/blob/master/docs/Guide.md#intercepting-hash-url-changes

一般来说,你差不多就到了,但是 YT 导航的工作方式使得无法通过 onNavigationStateChange 被捕获,这就是为什么我们注入一个 JS 代码来拦截这些哈希更改并发布消息到父组件,然后我们在 onMessage 处理程序中捕获它并正确设置状态变量.将 injectedJavaScriptonMessage 属性复制到您的示例中应该可以解决您的问题.

In general you were almost there, however the way the YT navigation works made it impossible to be caught via the onNavigationStateChange, that's why we inject a JS code that intercepts these hash changes and posts a message to the parent component, we then catch it inside the onMessage handler and set the state variable properly. Copying the injectedJavaScript and onMessage properties to your example should solve your problem.

我为您准备了一个组件,它似乎可以满足您的需求:

I prepared a component for you that seems to do what is needed:

 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

import React, { Fragment } from "react";
import {
  SafeAreaView,
  StyleSheet,
  ScrollView,
  View,
  Text,
  BackHandler,
  StatusBar
} from "react-native";
import { WebView } from "react-native-webview";
import {
  Header,
  LearnMoreLinks,
  Colors,
  DebugInstructions,
  ReloadInstructions
} from "react-native/Libraries/NewAppScreen";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.startingUrl =
      "https://m.***.com/channel/UCw3kP3qCCF7ZpLUNzm_Q9Xw/videos";
    this.handleBackButton = this.handleBackButton.bind(this);
  }

  componentDidMount() {
    BackHandler.addEventListener("hardwareBackPress", this.handleBackButton);
  }

  componentWillUnmount() {
    BackHandler.removeEventListener("hardwareBackPress", this.handleBackButton);
  }

  handleBackButton = () => {
    console.log(this.state);
    const { canGoBack } = this.state;
    if (canGoBack) {
      this.webView.goBack();
      return true;
    } else {
      return false;
    }
  };

  render() {
    return (
      <Fragment>
        <WebView
          source={{ uri: this.startingUrl }}
          style={{ marginTop: 20 }}
          ref={webView => (this.webView = webView)}
          injectedJavaScript={`
          (function() {
            function wrap(fn) {
              return function wrapper() {
                var res = fn.apply(this, arguments);
                window.ReactNativeWebView.postMessage('navigationStateChange');
                return res;
              }
            }

            history.pushState = wrap(history.pushState);
            history.replaceState = wrap(history.replaceState);
            window.addEventListener('popstate', function() {
              window.ReactNativeWebView.postMessage('navigationStateChange');
            });
          })();

          true;
        `}
          onMessage={({ nativeEvent: state }) => {
            if (state.data === "navigationStateChange") {
              // Navigation state updated, can check state.canGoBack, etc.
              this.setState({
                canGoBack: state.canGoBack
              });
            }
          }}
        />
      </Fragment>
    );
  }
}

export default App;