【问题标题】:Prevent Reload in React Native WebView防止在 React Native WebView 中重新加载
【发布时间】:2026-02-13 10:00:01
【问题描述】:

我正在一个 WebView 组件中运行一个单独的 Web 应用程序,在一个 React Native 应用程序中,我正在尝试让它们正常通信。

React Native 到 WebView 工作正常。我可以拨打webView.postMessage(...) 并在document.addEventListener("message", ...) 接收它,没有任何问题。

但是,当我尝试另一种方式(WebView 到 Native)时,对 window.postMessage triggers a url change via window.location 的调用似乎重新加载了整个 WebView,并破坏了其中的路由解决方案。

react-native-community/react-native-webview 组件似乎是have the same problem

有没有办法在不更改 URL 或导致页面重新加载的情况下从 Web 视图中向本机应用程序发送消息?

【问题讨论】:

  • 你有没有设法解决这个问题?我也遇到了同样的问题!

标签: reactjs react-native webview


【解决方案1】:

您可以在 IOS 示例中使用 onShouldStartLoadWithRequest 道具:-

import React, {Component, useCallback} from 'react';
import {
  BackHandler,
  Platform,
  SafeAreaView,
  ActivityIndicator,
  StyleSheet,
  Dimensions,
  Linking,
} from 'react-native';
import {WebView} from 'react-native-webview';
import Spinner from 'react-native-loading-spinner-overlay';


class SupportPayWebView extends Component {
  constructor(props) {
    super(props);
    
  }
  webView = {
    canGoBack: false,
    ref: null,
  };

  loader = {
    show: true,
  };

  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,
      );
    } else {
      BackHandler.addEventListener('hardwareBackPress', this.backHandler);
    }
  }

  componentWillUnmount() {
    
    if (Platform.OS === 'android') {
      BackHandler.removeEventListener('hardwareBackPress');
    } else {
      BackHandler.removeEventListener('hardwareBackPress', this.backHandler);
    }
  }

  backHandler = () => {
   
    this.webView.ref.goBack();
    return true;
  
  };

  ActivityIndicatorLoadingView() {
    return (
      <ActivityIndicator
        color="#009688"
        size="large"
        style={styles.ActivityIndicatorStyle}
      />
    );
  }
  
  onShouldStartLoadWithRequest = (navigator) => {
    
      this.webView.ref.stopLoading();
      return false;

  };
  render() {
    return (
      <>
        <WebView
          style={styles.WebViewStyle}
          onLoadEnd={() => {
            this.loader.show = false;
          }}
          injectedJavaScript={
            "const meta = document.createElement('meta'); meta.setAttribute('content', 'width=device-width, initial-scale=0.5, maximum-scale=0.5, user-scalable=0'); meta.setAttribute('name', 'viewport'); document.getElementsByTagName('head')[0].appendChild(meta); "
          }
          
          scalesPageToFit={true}
          automaticallyAdjustContentInsets={true}
          scrollEnabled={true}
          javaScriptEnabled={true}
          domStorageEnabled={true}
          renderLoading={this.ActivityIndicatorLoadingView}
          startInLoadingState={true}
          bounces={false}
          source={{uri: '}}
          ref={(webView) => {
            this.webView.ref = webView;
          }}
          onShouldStartLoadWithRequest={this.onShouldStartLoadWithRequest}
          
          sharedCookiesEnabled={true}
          // scalesPageToFit={false}
          javaScriptEnabledAndroid={true}
          userAgent="Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"
          // decelerationRate="normal"
        />
       


      </>
      // </SafeAreaView>
    );
  }
}

const styles = StyleSheet.create({
  WebViewStyle: {
    justifyContent: 'center',
    alignItems: 'center',

    marginTop: Platform.OS === 'ios' ? 35 : 0,
    width: '100%',
    height: '100%',
    resizeMode: 'cover',
    flex: 1,
  },

  ActivityIndicatorStyle: {
    position: 'absolute',
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

【讨论】: