React-native: [WebView] WebView not loading source / Staying in loading state

Created on 17 Feb 2016  路  38Comments  路  Source: facebook/react-native

Hello,

seems like there Is an issue with the WebView not loading its source.
I have followed the basic example on the DOCS and tried to load google.com and plain html. Either one didnt work.
RN V0.19.
Staying in loading state.

Sample code (nested component):

'use strict';
import React, {
  AppRegistry,
  Component,
  StyleSheet,
  Text,
  View,
  Image,
  TextInput,
  Button,
  TouchableHighlight,
  TouchableOpacity,
  StatusBarIOS,
  WebView
} from 'react-native';

StatusBarIOS.setStyle(1);

import Dimensions from 'Dimensions';
var width = Dimensions.get('window').width;
var height = Dimensions.get('window').height;

var CStyles = require('./CStyle');

class TestComp extends Component {
  constructor(){
    super();

    this.state = {
      url: 'https://www.google.at/'
    }
  }
  render() {
    return (
      <View style={{flex: 1}}>
          <WebView
            ref="webview"
            style={{width: width}}
            automaticallyAdjustContentInsets={false}
            source={{uri: this.state.url}}
            javaScriptEnabled={true}
            domStorageEnabled={true}
            decelerationRate="normal"
            startInLoadingState={true}
          />
      </View>
    );
  }
}
module.exports = TestComp;
Locked

Most helpful comment

In my case an alignItems: 'center' in the parent container was causing the problem.

All 38 comments

Hey noabyuna, thanks for reporting this issue!

React Native, as you've probably heard, is getting really popular and truth is we're getting a bit overwhelmed by the activity surrounding it. There are just too many issues for us to manage properly.

  • If you don't know how to do something or something is not working as you expect but not sure it's a bug, please ask on StackOverflow with the tag react-native or for more real time interactions, ask on Discord in the #react-native channel.
  • If this is a feature request or a bug that you would like to be fixed, please report it on Product Pains. It has a ranking feature that lets us focus on the most important issues the community is experiencing.
  • We welcome clear issues and PRs that are ready for in-depth discussion. Please provide screenshots where appropriate and always mention the version of React Native you're using. Thank you for your contributions!

+1

the problem is when I use the old prop named url it shows a warning says url has been deprecated, use source prop in version of 0.20, but use source it says source is invalid prop

Source has to be source={{ uri: YOUR_URL }}, whereas URL was just url={YOUR_URL}

Thanks @tomauty

@tomauty I am using {{uri: this.state.url }} and yet still it doesn't work

Any errors in Safari's developer console pointing to the simulator?

Unfortunately I get no errors in chrome live debugging and no errors in the app itself. I have an open SO question regarding that issue - we can continue over there so that his doesn't get spammed.

push

I had this issue when I put webview under view. An alternative solution is to move the webview out of the view(ex: as a root view), the webview came out. I thought this issue might be related to the iteration of view, because if you check the debug navigator in Xcode, there was abnormal numbers of RCTViews by a single request.

I was trying to reproduce this issue. where is the content for CStyle?
var CStyles = require('./CStyle');

Just some Basic Styling. I use it at an implemented style sheet

The webview is nested in a regular view with a flex .9 height and a header element above it with .1 height. Nothing more to the CStyles :)

i'm having the same issue :(

Also having this issue. WebView loads when it's the only component being returned, but not when it's nested inside a View component.

[edit] I'm not sure why, but my problem seems to have been solved by setting a width property in my WebView's styling. Possibly some issue with the parent's flex property?

Also not showing when nested inside of a View, works when it's alone.

+1

This is my tree:

<View style={styles.self}>

                <View style={styles.header.self}>
                    <Text>xxx</Text>
                </View>

                <View style={styles.content.self}>
                    {this.state.view}
                </View>

                <View style={styles.header.self}>
                    <Text>xxx</Text>
                </View>

            </View>

Workarround:

                {
                    !this.state.showBrowser &&
                    <View>
                        <Text>xxx</Text>
                    </View>
                }

                {
                    this.state.showBrowser &&
                    <WebView
                        source={{uri: this.state.url}}
                    </WebView>
                }

In my case an alignItems: 'center' in the parent container was causing the problem.

I render a top WebView (used for authorization and has redirects) in my component : startInLoadingState={true} causes the WebView to finish in a loading state. It means that its navigation state is always true. Or it should be false in the end.

This never happened after I've changed startInLoadingState property to false.

Closing this issue because it has been inactive for a while. If you think it should still be opened let us know why.

I think this issue should not be closed. It can only work when at top level, but not work under a tag.

shall we use https://github.com/jsdf/react-native-htmlview instead? working better?

That seems like a reasonable workaround.

well, I tryed htmlview, it's not fitting my needs: I would like to have a map (osm, leaflet) and other html pages inside my RN app, not a 'link launcher with an external browser' and I'm facing other problems:

  • WebView only renders on ios if https although there is a workaround which implies to declare the http website known urls
  • on android, WebView only renders if it's not a child of a View element
    I don't want to switch to angular/cordova/ionic as I'm coding a Mastodon social network client, which is written in React.
    I would like to have a working WebView to share my code to be cross-platform...

It doesn't work in React Native 0.44 with startInLoadingState set to true. I am trying to load a file from my web service into a webview.

<WebView
          source={{
            uri,
            headers: {"Authorization": `Bearer ${token}`},
            token: `${token}`,
          }}
          startInLoadingState={true}
          scalesPageToFit={false}
        />

@fengerzh was right, Webview only work on top level

It doesn't work in React Native 0.45 either. Flex:1 seems to not affect the WebView at all unless I set a specific width or height.

Having a similar issue with the WebView on a physical Android device, OnePlus 3T.

startInLoadingState renders the loading state, but the content never loads … unless I switch the WiFi on or off, then the WebView content loads instantly.

Same problem here.
Webview only works on top level.

@matthewvincent when it's nested inside a View component,you setting flex : 1 and webview's flex : 1,it does work

I've tried every single workaround mentioned in here, and combinations of them. I continue getting a blank screen. It doesn't work on the top level either.

Even I tried everything mentioned in the thread but nothing worked for me. At the end, I switched over to https://github.com/react-native-china/react-native-webkit-webview that uses WKWebView instead of UIWebView as recommended by apple for iOS 8 and above, and everything started working normally.

This is still an issue, but only on iOS. Android works perfectly fine. The issue is a hidden UIWebView never exits the loading state.

React Native: 0.52.2
iOS: 11.3

Can we get this reopened, @hramos?

Logging RCTWebView's webView.loading

I added a simple logging statement and it logs:

2018-06-07 22:32:34.481172-0500 HarvestPoint[52403:2799087] LOADING:: TRUE, TRUE

That's the only log it gets when startInLoadingState={true} on JS. If I turn that off, you'll see a list of TRUE, TRUE then a FALSE, FALSE which then renders the UI.

  NSLog(@"LOADING:: %@, %@", webView.loading  ? @"TRUE" : @"FALSE", webView.isLoading  ? @"TRUE" : @"FALSE");
  if (_injectedJavaScript != nil) {
    NSString *jsEvaluationValue = [webView stringByEvaluatingJavaScriptFromString:_injectedJavaScript];

    NSMutableDictionary<NSString *, id> *event = [self baseEvent];
    event[@"jsEvaluationValue"] = jsEvaluationValue;

    _onLoadingFinish(event);
  }
  // we only need the final 'finishLoad' call so only fire the event when we're actually done loading.
  else if (_onLoadingFinish && !webView.loading && ![webView.request.URL.absoluteString isEqualToString:@"about:blank"]) {
    _onLoadingFinish([self baseEvent]);
  }

The Fix

In WebView.ios.js, editing the hidden style fixes the loading:

  hidden: {
    height: 1,
    flex: 0, // disable 'flex:1' when hiding a View
  },

Originally the height is 0.

My Component

// @flow

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { WebView } from 'react-native';
import { Spinner } from 'native-base';

import * as actions from '../data/actions';
import { HPLoading } from '../components';

export class Iframe extends Component {
  static propTypes = {
    url: PropTypes.string,
  };

  render() {
    return (
      <WebView
        allowsInlineMediaPlayback={true}
        domStorageEnabled={true}
        renderLoading={this._renderLoading}
        source={{uri: this.props.url}}
        startInLoadingState={true}
      />
    );
  }

  _renderLoading = () => {
    return (
      <HPLoading />
    );
  }
}

@johncblandii - looks like the issue is in flexbox itself. My workaround is based on your finding, but without modifying the source code of WebView. Just wrapped webview into a custom component and return this in render() method:

<View style={this.props.style}>
  <WebView 
    style={ this.state.loading ? { flex: 0, height: 1 } : { flex: 1 } }
    source={this.props.source} 
    onLoadEnd={ () => this.setState({ loading: false }) } />
  { this.state.loading && 
    <ActivityIndicator animating size="large" style={{ flex: 0, width: '100%', height: '100%' }} />
  } 
</View>

I did test adjusting the style and many other options to no avail. The issue to me is RN shouldn't require people to implement workarounds for it to work properly.

That's why #19617 exists.

All I wanted to say is that they need to fix an underlying issue, which seems to be in RN flexbox implementation. I don't see any reason why it should work differently when setting height to 0. Setting height to 1 in WebView stylesheet fixes the symptoms, not the problem...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lazywei picture lazywei  路  3Comments

aniss picture aniss  路  3Comments

anchetaWern picture anchetaWern  路  3Comments

ghost picture ghost  路  3Comments

josev55 picture josev55  路  3Comments