ReactNative WebView not rendering on web, but works fine on Android - react-native

Used versions:
"expo": "^36.0.2",
"react": "16.9.0",
"react-dom": "^16.8.6",
"react-native": "0.61.4",
"react-native-web": "0.11.7",
"react-native-webview": "^8.1.2"
Used React Native code:
<WebView
source={{uri: 'https://www.somedomain.com/'}}
style={{marginTop: 22, flex: 1}}
injectedJavaScript={this.state.contentScript}
domStorageEnabled={true}
startInLoadingState={true}
onMessage={this.receiveMessage}
ref={this.props.webview}
/>
Only a red border is present on the web version meanwhile on the Android it loads fine.
No errors present. Could this be a known issue? But I can't find it reported anywhere.

Currently WebView is not supported by expo-web. Check Platform Compatibility for more information.
But if you want to load your WebView inside expo-web, place it inside iframe as below,
import * as React from "react";
import { View, Platform } from "react-native";
import { WebView } from "react-native-webview";
export default class App extends React.Component {
render() {
return Platform.OS === "web" ? (
<iframe src="https://www.somedomain.com/" height={'100%'} width={'100%'} />
) : (
<View style={{ flex: 1 }}>
<WebView
source={{ uri: "https://www.somedomain.com/" }}
style={{marginTop: 22, flex: 1}}
/>
</View>
)
}
}
Hope this helps you. Feel free for doubts.

Related

How to access camera in react native expo?

This is the code I am implementing to access camera in React Native Expo App. But this code is not working. It only shows blank screen and nothing else. Please suggest me if any changes required or any alternate method to implement this.
import React, { useState, useEffect } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import { Camera } from 'expo-camera';
export default function App() {
const [hasPermission, setHasPermission] = useState(null);
const [type, setType] = useState(Camera.Constants.Type.back);
useEffect(() => {
(async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View style={{ flex: 1 }}>
<Camera style={{ flex: 1 }} type={type}>
<View
style={{
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
}}>
<TouchableOpacity
style={{
flex: 0.1,
alignSelf: 'flex-end',
alignItems: 'center',
}}
onPress={() => {
setType(
type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back
);
}}>
<Text style={{ fontSize: 18, marginBottom: 50, color: 'red' }}> Flip </Text>
</TouchableOpacity>
</View>
</Camera>
</View>
);
}
It looks like somehow you have denied permission in App. Also In the code, if hasPermission is null you will see a blank page.
Note: In Ios, if you have denied or granted permission once, then the app will never show permission popup again until you use linking and let the user enable permission from setting.
It looks like the Camera.requestPermissionsAsync is now deprecated. You might try using Camera.requestCameraPermissionsAsync(). After I updated my code the deprecation notice disappeared.
The Camera component shouldn't in the <SafeAreaView>
<YOUR_CAMERA_COMPONENT /> /* <-- when outside the <SafeAreaView> , it work!*/
<SafeAreaView>
<YOUR_CAMERA_COMPONENT /> /* <-- it will show blank view */
</SafeAreaView>
I solved the problem when removed the <Camera /> from <SafeAreaView />
Firstly i am using:
"expo": "~40.0.0",
now im upgrading the cli and then using expo upgrade and everything fix itself:
"expo": "^41.0.0",
"expo-camera": "~11.0.2",
"expo-cli": "^4.4.1",
"expo-image-picker": "~10.1.4",
"expo-status-bar": "~1.0.4",
"firebase": "8.2.3",
The emulator camera doesn't support this library , try using in Android or Ios device and it will work perfectly fine.
Please check this example or the original Expo-camera library.
Hope it helps .feel free for doubts
I saw your code and I feels this code same as a expo-camera documentation.
I think you are trying this code on Emulator/Simulator . please try once on
Physical Device. because emulator doesn't support camera. you can read the document in brief https://docs.expo.io/versions/latest/sdk/camera/#requestpermissionsasync

scrollToLocation is undefined in sectionlist ref of react native, neither in flatlist

I have tried Flatlist, SectionList, Animated.Flatlist and Animated.SectionList,
Here is a simple example how to check scrollToLocation:
<SectionList
onLayout={this.onLayout.bind(this)}
ref={ref => {
this.sectionList = ref
console.log('ref.scrollToLocation: ' + CircularJSON.stringify(ref.scrollToLocation))
} }
ListHeaderComponent={() => <View style={{height:300, width:300, backgroundColor:'green'}}></View>}
sections = {[{key: 1, data: [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]}]}
renderItem = {() => <View style={{width:300, height: 100, marginBottom:20, backgroundColor:'red'}}></View>}
/>
Expected to see scrollToLocation method but showing undefined.
Please help me if you have any idea. Thanks!
Env:
"react": "16.6.3",
"react-native": "0.57.8",
Simulator: Xcode 10 iPhone X
Try Implementing This Way.
this.SectionList.scrollToLocation({sectionIndex,itemIndex})
render(){
return(<SectionList
ref={ref=>{this.SectionList = ref}}
otherProps
/>)
}

How to change uri value of Video component dynamically

I am working with react native, and I am using a video component from the expo. during this how I can change the value for URI attribute dynamically
(As you mentioned in the comment that you already solved the problem and want to play youtube videos)
You can use WebView to play Youtube video.
Working demo: https://snack.expo.io/Syhzx-VvX
Here is the sample code:
import React, { Component } from 'react';
import { StyleSheet, View, WebView, Platform } from 'react-native';
export default class App extends Component<{}> {
render() {
return (
<View style={{ height: 300 }}>
<WebView
style={ styles.WebViewContainer }
javaScriptEnabled={true}
domStorageEnabled={true}
source={{uri: 'https://www.youtube.com/embed/YE7VzlLtp-4' }}
/>
</View>
);
}
}
const styles = StyleSheet.create({
WebViewContainer: {
marginTop: (Platform.OS == 'android') ? 20 : 0,
}
});
Otherwise if you don't want to use WebView, use a third party package like react-native-youtube

useNativeControl with Expo Video component causing app to crash

Hi I am trying to use video with React Native and came across Expo Video Component (see https://docs.expo.io/versions/v14.0.0/sdk/video.html) and as I am using create-react-native-app to setup my app I thought this would be a good option. However when I add "useNativeControl to my video component it causes my app to crash.
Here is some code with useNativeControl: //displays just the controls for a second and then says "Expo has stopped" before exiting app
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, Button } from 'react-native';
import { Video } from 'expo';
export default class App extends Component {
render() {
return (
<View style={styles.app}>
<Video source={{ uri: 'http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4' }} rate={1.0} volume={1.0} useNativeControls muted={false} resizeMode="cover" shouldPlay isLooping style={{ width: 300, height: 300 }} />
</View>
);
}
}
Here is the code without it:
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, Button } from 'react-native';
import { Video } from 'expo';
export default class App extends Component {
render() {
return (
<View style={styles.app}>
<Header />
<Topics />
<Video source={{ uri: 'http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4' }} rate={1.0} volume={1.0} muted={false} resizeMode="cover" shouldPlay isLooping style={{ width: 300, height: 300 }} />
</View>
);
}
so as you can see the only difference is the "useNativeControls", without usenativecontrols the app works fine, I just don't have any controls on the video.
Main Question: How can I use native controls and not have my app crash?
Side Note/Question:
Alternatively, is there another video player that is simple to use for beginners of react-native? I have spent a few hours on this but haven't come up with a solution yet. I originally tried react-native-video (https://www.npmjs.com/package/react-native-video), but this did not work for me (and judging from the docs it requires you to make changes to java code which is not something I am looking to do). So if there is an alternative to expo's video component that has controls and works without any java/swift knowledge that is what I am looking for.
Edit:
package.json dependencies:
"dependencies": {
"expo": "^20.0.0",
"link": "^0.1.5",
"react": "16.0.0-alpha.12",
"react-native": "^0.46.4",
"react-native-video": "^2.0.0",
}
Have you ejected/detached your app? That library needs some native code to be added to a project. You cannot use it with plug&play method. Read more about detaching here: https://docs.expo.io/versions/latest/guides/detach.html
Be warned though, it's wild world once you start building an app for yourself. I am there by myself right now and failing wonderfully. I doubt you can find any video player that would not require some native code to be added.

React Native Webview not loading any url (React native web view not working)

I am trying to implement react native webview component in my application, but the web view is not loading any url its just showing the white page.
var React = require('react-native');
var{
View,
Text,
StyleSheet,
WebView
} = React;
module.exports = React.createClass({
render: function(){
return(
<View style={styles.container}>
<WebView source={{uri: 'https://m.facebook.com'}} style= {styles.webView}/>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex:1,
backgroundColor: '#ff00ff'
},webView :{
height: 320,
width : 200
}
});
Below is the screenshot of the output .
I had this issue. WebView would render when it was the only component returned, but not when nested in another View component.
For reasons I'm not entirely sure of the issue was resolved by setting a width property on the WebView component.
class App extends React.Component {
render() {
return (
<View style={styles.container}>
<WebView
source={{uri: 'https://www.youtube.com/embed/MhkGQAoc7bc'}}
style={styles.video}
/>
<WebView
source={{uri: 'https://www.youtube.com/embed/PGUMRVowdv8'}}
style={styles.video}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'space-between',
},
video: {
marginTop: 20,
maxHeight: 200,
width: 320,
flex: 1
}
});
I'm facing same issue. What I observed is that WebView doesn't work if it's nested. If component returns just WebView, then everything is fine.
Using the answers from other users, I was able to get my react native with webview working both inside a view and outside a view. My problem came down to two things. Being on the android emulator and behind a proxy, I just had to go to my browser (chrome) in the android emulator and sign in to the corporate proxy. Secondly, some sites work and others will not work. Whether the webview was nested or not inside of a View tag, some sites like cnn.com and slack.com etc will work fine, but no matter what settings I tried for google.com it wouldn't work (even though the proxy will definitely allow google.com) Lastly, when I rebuild my application and push to the emulator the new app, sometimes it took an inordinately long time to load any site. But once the site was loaded, the links are quick and responsive. So if you don't at first see something after a build, also be patient. Hope this helps someone else.
My final app.js
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
Dimensions
} from 'react-native';
import { WebView } from 'react-native';
const deviceHeight = Dimensions.get('window').height;
const deviceWidth = Dimensions.get('window').width;
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<View style={{flex:1}}>
<WebView
style={styles.webview}
source={{uri: 'https://www.slack.com'}}
javaScriptEnabled={true}
domStorageEnabled={true}
startInLoadingState={false}
scalesPageToFit={true} />
</View>
);
}
}
const styles = StyleSheet.create({
webview: {
flex: 1,
backgroundColor: 'yellow',
width: deviceWidth,
height: deviceHeight
}
});
WebView works well on Android. However you need to enable javascript and dom storage for some web pages.
<WebView style={styles.webView}
source={{uri: 'https://google.com/'}}
javaScriptEnabled={true}
domStorageEnabled={true}
startInLoadingState={true}
>
</WebView>
If you want the component to render the entire page, you need to wrap it with View that has flex: 1. The code below works for me:
<View style={{flex:1, alignItems: 'flex-end'}}>
<WebView
source={{uri: this.state.webContentLink}}
startInLoadingState={true}
scalesPageToFit={true} />
</View>
WebView is being moved to react-native-webview
.
None of the other answers worked except this method:
npm install --save react-native-webview
Then use it as follows:
<View style={{ flex: 1, alignItems: 'flex-end' }}>
<WebView
source={{
uri: 'https://www.yahoo.com',
}}
startInLoadingState={true}
scalesPageToFit={true}
style={{
width: 320,
height: 300,
}}
/>
</View>
<View>
<WebView
source={{uri: this.props.link}}
style={styles.webview}
javaScriptEnabled={true}
domStorageEnabled={true}
startInLoadingState={true}
/>
</View>
and style as follows:
const React = require('react-native');
const { Dimensions } = React;
const deviceHeight = Dimensions.get('window').height;
const deviceWidth = Dimensions.get('window').width;
export default {
webview: {
width: deviceWidth,
height: deviceHeight
}
};
All this to deal with bad webview dimension, so just set a specific height and specific width too (deviceHeight and deviceWidth as the example above).
As of June 2020 (noting the date because React Native answers seem to become out-of-date quickly), the simplest solution to this appears to be:
import React from 'react'
import { View, StyleSheet } from 'react-native'
import { WebView } from 'react-native-webview'
export const ComponentWithWebView = () => {
return (
<View style={styles.view}>
<WebView source = {{uri: 'https://www.google.com/'}} />
</View>
)
}
const styles = StyleSheet.create({
view: {
alignSelf: 'stretch',
flex: 1,
}
}
This results in a WebView filling the available space and being nested within a View. I believe the typical problems faced when placing a WebView within a View is that View expects children to force the View to expand (that is, a Text component would take up some amount of width and height which the View then accommodates). WebView, on the other hand, expands to the size of the parent component unless a style is passed specifying the width. Therefore, a simple <View><WebView /></View> results in a 0 width and nothing shown on the screen. The earlier solutions of setting the WebView width work well but require either the device dimensions to be fetched (which might not be the desired width) or for the View to have an onLayout function AND have some way to expand the View to the desired space. I found it easiest to just apply the flex: 1 and alignSelf: 'stretch' for the View to fill the space as desired and then WebView to automatically follow suit.
Hope this helps someone before it becomes obsolete!
I ran into the same issue recently. And I found that
alignment: 'center'
was causing the issue for me. I commented it and the webView got loaded immediately.
I found the solution here :
https://github.com/facebook/react-native/issues/5974
'brunocvcunha's' response worked for me.
Let me give the simplest example which will work seamlessly:
import React from 'react';
import { WebView } from 'react-native';
export default class App extends React.Component {
render() {
return (
<WebView
source={{uri: 'https://github.com/facebook/react-native'}}
/>
);
}
}
Do not add your WebView component within a view that created problem and webview url is not rendered rather styles of view will be shown.
I had the same issue and spent a day attempting to fix it. I copied in the UIExplorer webview example, and that didn't work.
I ultimately ended up upgrading react and creating a new react-native project and copying the files in there, and that fixed it.
I wish I had a better answer as to why that fixed it, but hopefully that helps
Below is piece of the code which worked for me.
render: function(){
return(
<View style={styles.container}>
<WebView url={'https://m.facebook.com'} style= {styles.webView}/>
</View>
);
}
I am doing React Native Webview, Could you please suggest me how to makeWebview loading the uri
render() {
return (
<Modal
animationType="slide"
ref={"webModal"}
style={{
justifyContent: 'center',
borderRadius: Platform.OS === 'ios' ? 30 : 0,
width: screen.width,
height: screen.height,borderColor:'red',
borderWidth: 5
}}
position='center'
backdrop={false}
onClosed={() => {
// alert("Modal closed");
}}>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: 20, top: 10 }} >
<Text style={{ fontSize: 24, fontWeight: '700' }}>
Interests
</Text>
<Icon name="ios-close" size={40} color='purple' onPress={() => { this.refs.webModal.close() }} />
</View>
<WebView
source={{ uri: this.state.link }}
style={{ marginTop: 20,borderColor:'green',
borderWidth: 5 }}
/>
</Modal>
);
}
}
import { WebView } from 'react-native'; is deprecated
use below line instead
npm install react-native-render-html#4.1.2 --save
then
import HTML from 'react-native-render-html';
react-native-render-html starting with version 4.2.0, react-native-webview is now a peer dependency. As a result, you need to install it yourself.
Try
<WebView
source={{ uri: "https://inhall.in/" }}
style={Styles.webView}
javaScriptEnabled={true}
scalesPageToFit />
javaScriptEnabled={true} might help