Problem. The WebView is empty in React Native. However, the link works.
The code :
import React from 'react';
import { StyleSheet, View, WebView } from 'react-native';
import { Constants } from 'expo';
export default class App extends React.Component {
render() {
return (
<View>
<View style={styles.statusBar} />
<WebView
source={{uri: 'https://lapommeculturelle.com'}}
renderError={() => alert('Merci de vérifier votre connexion Internet - Internet non disponible')}
/>
</View>
);
}
}
const styles = StyleSheet.create({
statusBar: {
backgroundColor: "#1D3B57",
height: Constants.statusBarHeight,
}
});
For this project, I used Expo XDE. Thanks.
I believe you need to be specifying the height and width of the webview, as well as specifying the flex for the wrapping view.
Try this:
<View style={{flex:1}}>
<View style={styles.statusBar} />
<WebView
style={{height: 300, width: 300}}
source={{uri: 'https://lapommeculturelle.com'}}
renderError={() => alert('Merci de vérifier votre connexion Internet', 'Internet non disponible')}
/>
</View>
At the bare minimum, you need a style for the View that wraps the rest of them.
I'd recommend <View style={{flex: 1}}> just to get you started.
In an ideal world, you'd make that a style associated with your container and be pulling it from your StyleSheet:
import React from 'react';
import { StyleSheet, Text, View, WebView, ActivityIndicator } from 'react-native';
import { Constants } from 'expo';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<View style={styles.statusBar} />
<WebView
source={{uri: 'https://lapommeculturelle.com'}}
renderError={() => alert('Merci de vérifier votre connexion Internet', 'Internet non disponible')}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
statusBar: {
backgroundColor: "#1D3B57",
height: Constants.statusBarHeight,
}
});
My fix for iOS, for some reason, is this style:
<WebView
// fixes warning when page has an iframe (about:srcdoc)
originWhitelist={['http://*', 'https://*', 'about:srcdoc']}
renderLoading={this._renderLoadingWebView}
scrollEnabled
source={{ uri }}
style={{ borderWidth: 1, borderColor: 'transparent' }}
/>
react-native-webview 7.5.2
Related
I am new to learning React Native and I would like to build a (ReactNaive & Expo) application with a good interface look, How can I build a component and send style{backgroundColor} as props then render the component on Home
home.js
import React from 'react'
import { View, Text , Image , ScrollView} from 'react-native';
import { FlatList } from 'react-native-gesture-handler';
import { COLORS, SIZES,FONTS} from '../styles/theme.js';
import Category from '../components/Category.js';
import CategorySlider from '../components/CategorySlider'
const Home = () => {
function renderHeader(){
return(
<View
style = {{
flexDirection: 'row' ,
marginTop: 40,
marginBottom: 10,
paddingHorizontal:SIZES.padding,
alignItems : 'center'
}}
>
<View style={{flex:1}}>
<Text >Hello , Wafa</Text>
</View>
{/* Nonfiction Button */}
</View>
)}
return (
<View
style ={{
flex: 1,
backgroundColor: COLORS.white
}}
>
{/* HEADER */}
{renderHeader()}
{/* Content */}
<View style={{height:130 , marginTop:SIZES.margin}}>
<ScrollView
horizontal={true}
showsHorizontalScrollIndicator={false}
>
<Category name='Balance' />
<Category name='Saving' style={COLORS.green} />
<Category name='Income' style={ COLORS.brown } />
<Category name='Loans' style={ COLORS.pink}/>
<Category name='Saving' style={ COLORS.pink}/>
<Category name='Saving' style={ COLORS.pink}/>
</ScrollView>
</View>
<CategorySlider/>
</View>
)
}
export default Home;
It is the component I want to render on home.js
Category.js
import React, { PureComponent } from 'react'
import { Text, View ,StyleSheet ,Image } from 'react-native'
import { backgroundColor } from 'react-native/Libraries/Components/View/ReactNativeStyleAttributes';
import { COLORS, SIZES,FONTS} from '../styles/theme.js';
export default class Category extends PureComponent {
render() {
return (
<View style={{marginLeft: SIZES.margin ,marginRight: SIZES.margin}}>
<View>
<View style={{
height: 60,
width: 60,
backgroundColor:COLORS.pink,
borderRadius: SIZES.radius,
}}>
<View />
<View>
<Image />
</View>
</View>
<Text
style={{textAlign:'center'}}
>
{this.props.name}</Text>
</View>
</View>
)
}
}
l made also File for Design system contains style I will repeat on the application.
theme.js:
import { Dimensions } from "react-native";
import { useFonts } from 'expo-font';
const { width, height } = Dimensions.get("window");
export const COLORS = {
green: "#68AB9F",
brown: "#c18e62",
pink: "#d99e96" ,
gray: "#383e42",
white: "#f5f7fc",
}
Here you're working on one with a Functional based component (home.js) and one with Class-based (Category.js). Standard is if first convert your Category component with functional then you can save that props to your Category component like:
import React, { useState } from 'react'
import { Text, View ,StyleSheet ,Image } from 'react-native'
import { backgroundColor } from 'react-native/Libraries/Components/View/ReactNativeStyleAttributes';
import { COLORS, SIZES,FONTS} from '../styles/theme.js';
const Category = (props) => {
const [backgroundColor, setBackgroundColor] = useState(props.style || null); //store your prop in state like this
const [name, setName] = useState(props.name || null);
return (
<View style={{marginLeft: SIZES.margin ,marginRight: SIZES.margin}}>
<View>
<View style={{
height: 60,
width: 60,
backgroundColor: backgroundColor,
borderRadius: SIZES.radius,
}}>
<View />
<View>
<Image />
</View>
</View>
<Text
style={{textAlign:'center'}}
>
{name}</Text>
</View>
</View>
)
}
export default Category;
Hope this works for you.
In your parent component take your style object in the wrapper of child component i.e.
function Parent(){
return (
<Child cssdata={{backgroundColor:'red',marginLeft:8}}/>
)
}
and in your child component take this data from props and applied to it
function Child(props){
return (
<View style={props.cssdata}></View>
)
}
I have a simple React Native project in Expo, it launches a website using react-native-webview.
Here is the source code:
import React from "react";
import { StyleSheet, View, SafeAreaView } from "react-native";
import { AntDesign } from "#expo/vector-icons";
import { WebView } from "react-native-webview";
export default function App() {
const goback = () => {
WebView.goBack();
};
return (
<SafeAreaView>
<WebView source={{ uri: "https://google.co.uk" }} />
<View style={styles.navbar}>
<View style={styles.forward}>
<AntDesign name="right" size={25} color="grey" />
</View>
<View style={styles.back}>
<AntDesign name="left" size={25} color="grey" onPress={goback} />
</View>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
navbar: {
height: 40,
width: "100%",
flexDirection: "row-reverse",
paddingTop: 6,
backgroundColor: "#fefefe",
borderTopColor: "grey",
borderTopWidth: 1,
},
back: {
width: 50,
height: 50,
marginRight: 10,
},
forward: {
width: 50,
height: 50,
},
});
The WebView component loads the website fine (google.co.uk) but I can not get the navigation to work. I simply want to create a back button, that allows the user to navigate back to other pages they have viewed in the WebView, and forward if they have gone back and want to go forward.
For now I am trying to get the back button working. I load the app, then navigate to a different page on the WebView. When the back button is pressed, the following error is generated:
TypeError: _reactNativeWebview.WebView.goBack is not a function (In
'_reactNativeWebview.WebView.goBack()','_reactNativeWebview.WebView.goBack'
is undefined)
According to the doc's the goBack() method exists:
goBack()
I found this but it is implementing a class based component so I couldn't easily map the suggestions into my functional component, and further, I think that solution is overkill as they are intercepting the navigation, I believe what I am trying to achieve should be simpler, but I can't get the basic navigation to work on the WebView (i.e. go back and forward to previously viewed pages).
Everything mentioned by you is correct Gary. The only thing that you need to change is the way how goBack function is called. goBack is not a component's direct function rather you need to pass on a reference to the WebView component to get this function. In your case you can change your component as below to get this working:-
import React, { useRef } from "react";
import { StyleSheet, View, SafeAreaView } from "react-native";
import { AntDesign } from "#expo/vector-icons";
import { WebView } from "react-native-webview";
export default function App() {
const webViewRef = useRef(null)
const goback = () => {
webViewRef.current.goBack();
};
return (
<SafeAreaView>
<WebView ref={webViewRef} source={{ uri: "https://google.co.uk" }} />
<View style={styles.navbar}>
<View style={styles.forward}>
<AntDesign name="right" size={25} color="grey" />
</View>
<View style={styles.back}>
<AntDesign name="left" size={25} color="grey" onPress={goback} />
</View>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
navbar: {
height: 40,
width: "100%",
flexDirection: "row-reverse",
paddingTop: 6,
backgroundColor: "#fefefe",
borderTopColor: "grey",
borderTopWidth: 1,
},
back: {
width: 50,
height: 50,
marginRight: 10,
},
forward: {
width: 50,
height: 50,
},
});
This refernce will help you in calling any reference functions mentioned in the documentation of webview module. Enjoy!
also you can see different usage of webview in this package. https://github.com/ilkerkesici/react-native-beauty-webview
I want to display a custom message after successful record update when boolean value of recordUpdateSuccess become true and after 3seconds it should disappear.
{recordUpdateSuccess ? this.renderRecordUpdatedSucess() : null}
I have function to display message:
renderRecordUpdatedSucess = () => (
<View style={styles.sucessAlert}>
<Text style={styles.sucessAlert}>Record updated successfully.</Text>
</View>
)
I tried to use setTimeout() to display message but not working.
Any idea to acheive this one.
I don't want to use Toast, any third party library for this one.
Custom flash message (No external Library)
Working Example: https://snack.expo.io/#msbot01/1dcddc
import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
flashMessage: false
}
}
onPress(){
this.setState({
flashMessage: true
},()=>{setTimeout(() => this.closeFlashMessage(), 3000)})
}
closeFlashMessage(){
this.setState({
flashMessage: false
})
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={()=>{this.onPress()}}>
<Text>Click Me</Text>
</TouchableOpacity >
{this.state.flashMessage==true?
<View style={styles.flashMessage}>
<Text style={{color:'white'}}>This is custom Flash message</Text>
</View>
:
null
}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
flashMessage:{
position:'absolute',
backgroundColor:'green',
width:'100%',
justifyContent:'center',
alignItems:'center',
height:40,
top:0
}
});
i have been working on a form in which i need to get a background image to make it look more beautiful. when i use form components inside the image tag it shows the following error
im giving the code below that i used
import React,{Component} from 'react'
import {Image,View,Dimensions,ImageBackground} from 'react-native'
let {height,width}=Dimensions.get('window')
class DearImage extends Component {
render() {
return (
<View >
<Image source={require('../drawable/Auntie.jpeg')}
width={width}
height={height} >
{this.props.children}
</Image>
</View>
);
}
}
export default DearImage;
Your error shows you need to set your Image to absolute position, to avoid this you can use ImageBackground .and Image Tag cant have any children tag directly, Use a View instead well use like the below code, it will work for you
import React,{Component} from 'react'
import {Image,View,Dimensions,ImageBackground} from 'react-native'
let {height,width}=Dimensions.get('window')
class DearImage extends Component {
render() {
return (
<ImageBackground
source={require('../drawable/Auntie.jpeg')}
style={{
backgroundColor: '#ccc',
flex:1,
width: '100%',
height: '100%',
justifyContent: 'center',
}} >
<View style={{flex:1,position:"absolute", backgroundColor: 'transparent', }}>
{this.props.children}
</View>
</ImageBackground >
)
}
}
export default DearImage;
render() {
return (
<View>
<Image source={require('../drawable/Auntie.jpeg')}
width={width}
height={height}>
</Image>
<View style={{flex:1,position:"absolute"}}>
{this.props.children}
</View>
</View>
)
}
Use ImageBackground instead of Image.
import React,{Component} from 'react'
import {Image,View,Dimensions,ImageBackground} from 'react-native'
let {height,width}=Dimensions.get('window')
class DearImage extends Component {
render() {
return (
<ImageBackground source={require('../drawable/Auntie.jpeg')}
width={width}
height={height}
style = {{flex:1}}>
{this.props.children}
</ImageBackground>
)
}
}
export default DearImage;
For some reason, my react-native webview doesn't show up at all. Nothing shows up after my text field. Here's my code
import React, { Component } from 'react';
import {
View,
Text,
WebView,
} from 'react-native';
export default class Home extends Component {
render() {
return (
<View style={{flexDirection:'column'}}>
<Text>Show webview</Text>
<WebView source={{html:"<html><body style='color:red'>Hello<br/>This is a test</body></html>"}} style={{width:200,height:200,backgroundColor:'blue',marginTop:20}} />
</View>
);
}
}
What am I doing wrong?
Add flex: 1 to your <View /> component.
<View style={{flex: 1, flexDirection:'column'}}>
<Text>Show webview</Text>
<WebView source={{html:"<html><body style='color:red'>Hello<br/>This is a test</body></html>"}} style={{width:200,height:200,backgroundColor:'blue',marginTop:20}} />
</View>
Here's a demo
According to the ReactNative docs as of (Nov 2019) they say this:
Warning Please use thereact-native-community/react-native-webviewfork of this component instead. To reduce the surface area of React Native, <WebView/> is going to be removed from the React Native core. For more information, please read The Slimmening proposal.
I wasn't able to get the ReactNative <WebView/> to work at all in my Expo app. So switching to the react-native-community/react-native-webview <WebView/> component worked for me. I hope that helps!
Try out this:
import { WebView } from 'react-native-webview';
export default AppWebview = () => (
<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
}
});