The method stopLoading of react-native-webview causes the website to freeze

一曲冷凌霜 提交于 2020-12-09 13:42:04

问题


I want to intercept clicks on a link in my webview in react-native and perform a custom action instead of navigating to the target of the link as described in the official guide. Here's what I do:

import React from 'react';
import {View, Linking} from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
import {WebView} from 'react-native-webview';

export default class WebViewScreen extends React.Component {
    static navigationOptions = {
        title: 'Produck',
    };

    constructor(props) {
        super(props);
    }

    /**
     * Defines content and look of the WebViewScreen.
     */
    render() {
        const DEFAULT_URL = "https://www.myurl.de/index.html";

        return (
            <View style={{ flex: 1 }}>
                <WebView
                    ref = {webview => {
                        this.myWebView = webview;
                    }}
                    renderLoading = {this.renderLoading}
                    startInLoadingState = {true}
                    automaticallyAdjustContentInsets = {true}
                    source = {{ uri: DEFAULT_URL }}
                    javaScriptEnabled = {true}
                    domStorageEnabled = {true}
                    cacheEnabled = {false}
                    useWebKit = {true} // use WKWebView on iOS (http://facebook.github.io/react-native/blog/2018/08/27/wkwebview)
                    onNavigationStateChange={this.handleWebViewNavigationStateChange.bind(this)}
                />
            </View>
        );
    }

    handleWebViewNavigationStateChange = newNavState => {
        const {url} = newNavState;
        if (!url) return;

        if (isExternal(url)) {
            this.myWebView.stopLoading();

            // do something else, e.g.
            Linking.openURL(url);
        }
    };

}

If I click on a link in that webview the URL will be opened in a the systems Browser as expected. The problem is however that afterwards the webview is frozen. I can't click any more Links or even scroll the page. Of course this is not as it should be. The whole point is to open a link somewhere else so that the page in the webview remains usable. The result will remain the same, even if I remove the Linking-part. Then the page just freezes on a link-click.

Does anyone know what to do? I guess the stopLoading-method does a little more than just abort loading. Does it maybe also cancel any running Javascript on the current page? If so, can I prevent that?


回答1:


I have found a solution at least for my case thanks to this pull request. Instead of using onNavigationStateChange and stopLoading I turned to onShouldStartLoadWithRequest. In the callback method for this event you can define whether or not the request should be discarded as far as the current webview is concerned or not simply by returning false or true. So you get something like this:

render() {
    ...
    return(...
        <WebView
            ...
            onShouldStartLoadWithRequest={this.handleWebViewRequest.bind(this)}
            ...
        />
    );
}

handleWebViewRequest = request => {
    const {url} = request;
    if (!url) return false;

    if (isExternal(url)) {
        Linking.openURL(url);
        return false;
    } else {
        return true;
    }
}

So far for the "what to do"-part. Well I also wanted to answer my other questions and dug into the code of react-native-webview (which was no fun at all... what about comments? -> 'let the code speak' -> well it doesn't). After spending some time jumping from one delegation target to the next, somewhere the stopLoading-call seems to be handed over to the native WebView. So the behaviour may also be completely different for Android and iOS (I'm developing only for Android currently). As for the "can I prevent"-part of the whole question I can say: "No". Of course the most interesting part would have been "what does stopLoading actually do? Somewhere I read that it prevents Links on the current page from being clicked, indeed. But that was just a non-proven statement. As I got to the native Android-WebView-documentation I found the very very good explanation "Stops the current load." (go Google, yay). Then I lost all motivation to dig deeper. Well, unless someone more enlightned than me, can come up with a more elaborate explanation I will problably accept my own answer, since it is at least a solution to the dev-problem I faced.



来源:https://stackoverflow.com/questions/57043298/the-method-stoploading-of-react-native-webview-causes-the-website-to-freeze

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!