Image rendering issues React Native - javascript

I am building a react native app using mock data. I am able to render some of the mock data in a flatlist but the image will not render. In the react native devtools it shows the image url but no style is shown even though I have the style in the Stylesheet element.
import React, { Component } from "react";
import { StyleSheet, Text, View, Image, ListView } from "react-native";
class BookItem extends Component {
render(){
return (
<View style = {styles.bookItem}>
<Image style = {styles.cover} /> //is this the issue?
<View style = {styles.info}>
<Text style = {styles.author}>{this.props.author}</Text>
<Text style = {styles.title}>{this.props.title}</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
bookItem: {
flexDirection: "row",
backgroundColor: "#FFFFFF",
borderBottomColor: "#AAAAAA",
borderBottomWidth: 2,
padding: 5,
height: 175
},
cover: {
flex: 1,
height: 150,
resizeMode: "contain"
},
info: {
flex: 3,
alignItems: "flex-end",
flexDirection: "column",
alignSelf: "center",
padding: 20
},
author: { fontSize: 18 },
title: {fontSize: 18, fontWeight: "bold"}
});
export default BookItem
Im not sure if I am using the Image element in react native properly. This could be the issue. For the most part it shows the data in the devtools

You have to use image with source property. If you want to to add a just background you should use just View with background style.
Look at the official doc from here
Example is at the below.
<Image
style={{width: 50, height: 50}}
source={{uri: 'https://facebook.github.io/react-native/docs/assets/favicon.png'}}
/>

You mentioned a flatlist but the code sample you provided does not have a flatlist.
Refer to the documentation for more information.
https://facebook.github.io/react-native/docs/image.html
Here are the examples provided in the documentation.
<Image
source={require('/react-native/img/favicon.png')}
/>
<Image
style={{width: 50, height: 50}}
source={{uri: 'https://facebook.github.io/react-native/docs/assets/favicon.png'}}
/>
<Image
style={{width: 66, height: 58}}
source={{uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg=='}}
/>
Could you maybe mock up your problem for us?
https://snack.expo.io/

Two things: Image component needs a source prop to render an image and second, try not to use flex with images. Usually they need width AND height property manually set to render properly.

Change the value for resizeMode to cover instead of contain. This has resolved the same issue for me.

I had the same problem, i suggest you update react-native to version 0.63.3
It will probably cause errors, in which case you could use this React-Native upgrade helper.
https://react-native-community.github.io/upgrade-helper/

Related

How to fix Error not warning: ERROR VirtualizedLists should never be nested inside plain ScrollViews. Even when ScrollViews isn't used

I am trying to build a react-native app, and I want to build a layout where I have components in a vertical manner and a transaction history, I am stuggling with the component to view transaction history which I am populating from a dummy data, I am faced with an error "VirtualizedLists should never be nested inside...". Even when I am not using ScrollViews. I have tried a couple of stackoverflow answers but it is still the Error (Not warning). Here is my Code:
`
import React from 'react';
import {View, Text, FlatList, TouchableOpacity, Image} from 'react-native';
import {colors, SIZES, fonts, icons} from '../global';
const TransactionHistory = ({customContainerStyle, history}) => {
const renderItem = ({item}) => (
<TouchableOpacity
style={{
flexDirection: 'row',
alignItems: 'center',
paddingVertical: SIZES.base,
}}
onPress={() => console.log(item)}>
<Image
source={icons.transaction}
style={{
width: 30,
height: 30,
tintColor: colors.primary,
}}
/>
<View style={{flex: 1, marginLeft: SIZES.radius}}>
<Text style={{...fonts.android.h3}}>{item.description}</Text>
<Text style={{color: colors.gray, ...fonts.android.body4}}>
{item.date}
</Text>
</View>
</TouchableOpacity>
);
return (
<View
style={{
marginTop: SIZES.padding,
marginHorizontal: SIZES.padding,
padding: 20,
borderRadius: SIZES.radius,
backgroundColor: colors.white,
...customContainerStyle,
}}>
<Text style={{...fonts.android.h2}}>Transaction History</Text> //Transaction History Heading
<FlatList
contentContainerStyle={{marginTop: SIZES.radius}}
scrollEnabled={false}
data={history}
keyExtractor={item => `${item.id}`}
renderItem={renderItem}
showsVerticalScrollIndicator={false}
ItemSeparatorComponent={() => {
return (
<View
style={{
width: '100%',
height: 1,
backgroundColor: colors.lightGray,
}}></View>
);
}}
/>
</View>
);
};
export default TransactionHistory;
`
What I tried?
One of the answers was to change the ScrollView tag to View, but I already used the view tag and not ScrollView.
Change ScrollEnabled to be False. This was false initially.
According to this solution (React-Native another VirtualizedList-backed container). I used I created the Flatlist outside of the View and used ListFooterComponent to call it. Still the same Error.
Expected Outcome:
I am Meant to have the populated data after the Transaction History Heading. Please let me know, if there is any solution to this, or another way to fufill the task. Thanks
I had a similar issue once where I was using a ScrollView in a shared Container parent component. Maybe worth checking again to see if TransactionHistory isn't nested under and ScrollView parent somewhere on the Screen.
Once I figured it was nested under a ScrollView, I essentially removed the Container and added the header and footer component around my SectionList using the ListHeaderComponent and ListFooterComponent props on the SectionList achieving the same functionality of having a ScrollView parent.
Example:
<SectionList
renderSectionHeader={renderSectionHeader}
sections={data}
ListHeaderComponent={Header}
renderItem={renderItem}
contentContainerStyle={{ paddingBottom: bottom }}
/>
More info here

Why are views not displayed in react-native?

I am learning react-native and am very new to it. So, when I was learning to use flexbox, I ran into an issue. The issue was, the views are not being displayed when inside another view. My code =
import React from "react";
import { View, StyleSheet } from "react-native";
class App extends React.Component {
render() {
return (
<View style={styles.container}>
<View backgroundColor="red" />
<View backgroundColor="blue" />
<View backgroundColor="green" />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
});
export default App;
If you run this program, you will get a blank screen. I don't know why this is happening, and I also want to know how to fix it. By the way, I am running it in Iphone 11 simulator
You have set BackgroundColor directly to the View which is not possible. It has to be in the "Style" param. Also you have no height and width set to the View.
You can either do it inside the View directly like this:
<View style={{ backgroundColor: "red", height: 20, width: "100%"}} />
or create a new Style in your StyleSheet and then pass that to the View.

React Native: Image doesn't show in the view

sorry if I am reposting a question but I can't find one that would explain this.
My render() function returns this in my React Native application.
<View style={styles.login_card_view}>
<Text>aaa</Text>
<Image source={require('./logo_full.png')} style={{width: 200, height: 40}}/>
<Text>bbb</Text>
<Card>
...
</Card>
<Button containerStyle={{ marginTop: 20, alignItems: 'center', flex: 1}} />
</View>
This only results in an empty space for the image. (Image is in the same place as my class component.) Image doesn't show in that space but two of my texts 'aaa' and 'bbb' has a difference of 40. (That is the given height for the image.)
Am I using the Image component wrong? This is exactly similar to the documentation. Any help appreciated! Thanks.
import {View,StyleSheet, Text , Button , Image} from 'react-native';
import React , {Component} from 'react';
export default class BasicExample extends React.Component{
render (){
return (
<View>
<Text>aaa</Text>
<Image source={require('./logo_full.png')} style={{width: 200, height: 40}}/>
<Text>bbb</Text>
</View>
)
}
}
I run this code and it works for me. remember to put image location and name correctly. your code may have error like button without
title.
I think if you use like this
<Image source={require('/logo_full.png')} style={{width: 200, height: 40}}/>
it can be work.

Flex header layout in React Native

I'm new here on react native, And i was trying to align the back button to the left, But keeping the title on the center, But nothing works, This is the code.
The TouchableOpacity is the back button, And the Text is the title, Each one have his own style.
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, Image } from 'react-native';
import { Colors } from '../Variables';
class Header extends Component {
render(){
return(
<View style={ styles.headerStyle }>
<TouchableOpacity>
<Image style={ styles.backBtnStyle } source={ require('../graphics/icons/arrow_left_white.png') }/>
</TouchableOpacity>
<Text style={ styles.titleStyle }>
TITLE
</Text>
</View>
);
}
}
const styles = {
headerStyle: {
backgroundColor: Colors.primary,
flexDirection: 'row',
alignItems: 'center',
},
backBtnStyle: {
width: 25,
height: 25,
margin: 10,
},
titleStyle: {
color: '#fff',
textAlign: 'center',
fontSize: 25,
}
};
export default Header;
Thanks for helping.
You should try to view this document about Flex in React native and practive more to mastered it.
In Your case, just simplify add alignSelf: 'flex-start' to backBtnStyle StyleSheet to make it in first of your parent component
Here is demo code:
headerStyle: {
backgroundColor: Colors.primary,
flexDirection: 'row',
alignItems: 'center',
alignSelf: 'flex-start'
},
<TouchableOpacity style={styles.backBtnStyle}>
<Image source={require('../graphics/icons/arrow_left_white.png') }/>
</TouchableOpacity>
You see: TouchableOpacity contain a Viewable Layout and wrap your image then you need to set style for TouchableOpacity to make flex work, not at Image.
From React NativeTouchableOpacity Documents: Opacity is controlled by wrapping the children in an Animated.View, which is added to the view hierarchy. Be aware that this can affect layout.
You can see Touchable Opacity Document here
Note: Set Your StyleSheet on StyleSheet.create() to make it create one and only one time when your bundle load. It make your app light weight and faster
Read about React Native StyleSheet here
You are using alignItems: 'center' in your container, so everything will be in the center.
In your case, there are a lot of solutions available. The more simple is just use a position: absolute; left: 15 in the styles.backBtnStyle.

Updating State not updating view

I am currently learning React Native.
I have built a view which should show a text Loading when the data is being fetched and should display the data once the data has been received by the app.
The app is hitting the backend server and is getting the URL(tried console.error on app and it does popup with ared screen showing the correct data details ).
The problem is the view is not being updated. Another thing that is weird is that the conditional view is showing the border which has been set for the container, but it does not display any text or data except that. Even if I put the correct data. Not sure if the condition is being validated correctly or not.
The border I mentioned is set in articleContainer in the stylesheet and is attached with the container which is with the condition this.state.hasResult
If i remove the style from that view the border dissappears obviously but even putting a static text inside the view is not being displayed(checked incase I parsed the json wrong.) Seems a bit confusing.
var constants = require("../constants")
var React = require('react');
var ReactNative = require('react-native');
var t = require('tcomb-form-native');
var authenticate = require("../services/authenticate")
var {
AppRegistry,
AsyncStorage,
StyleSheet,
Text,
View,
TouchableHighlight,
Alert,
ListView,
Image,
} = ReactNative;
const options = {}
class RecipePage extends React.Component{
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1.id !== r2.id});
var getData = require("../services/get_featured");
var par = this;
var recipeId = props.recipeId;
this.state ={
hasResult: false,
noResult: false,
result: null,
isLoading: true,
}
getData(recipeId).then(function(data){
par.setState(
{
result:data,
hasResult:true,
noResult:false,
isLoading:false
}
)
}).catch(function(error) {
console.error(error);
});
}
goBack(){
this.props.navigator.pop();
}
render() {
return (
<View style={styles.container}>
<View style={styles.row}>
<Text style={styles.title}>Recipe</Text>
<TouchableHighlight onPress={this.goBack.bind(this)}>
<Image style={styles.back}
source={require("../static/images/back.png")}
/>
</TouchableHighlight>
</View>
{
this.state.hasResult &&
<View style={styles.article_container} >
<Text style={styles.article_title} >{this.state.result.id}</Text>
<Image style={styles.article_img}
source={{uri: this.state.result.image_link}}
/>
</View>
}
{
this.state.isLoading &&
<View style={styles.article_container} >
<Text style={styles.article_title} >Loading</Text>
</View>
}
</View>
);
}
}
var styles = StyleSheet.create({
container: {
justifyContent: 'center',
marginTop: 25,
padding: 20,
backgroundColor: '#ffffff',
},
title: {
fontSize: 30,
alignSelf: 'center',
marginBottom: 30
},
article_container: {
justifyContent: 'center',
marginTop: 5,
padding: 20,
backgroundColor: '#ffffff',
borderBottomColor: '#555555',
borderBottomWidth: 1,
flex:1
},
article_title: {
fontSize: 25,
alignSelf: 'center',
marginBottom: 3,
flex:2
},
article_img: {
width:200,
height:200,
alignSelf: 'center',
flex:1
},
article_description :{
fontSize:15,
flex:3
},
back:{
backgroundColor:'#ffffff',
width:20,
height:20
}
});
module.exports = RecipePage;
If you think I can improve the code not relating to this question, then feel free to comment and enlighten me :)
Edit:
I played around a bit more and found that if I change the attached styles as:-
<View style={styles.row} >
<Text style={styles.title} >{this.state.result.title}</Text>
<Image
source={{uri: this.state.result.image_link}}
/>
</View>
from
<View style={styles.article_container} >
<Text style={styles.article_title} >{this.state.result.id}</Text>
<Image style={styles.article_img}
source={{uri: this.state.result.image_link}}
/>
</View>
I am able to view the title after making this change, but image is still not displayed. And I am not sure why it was not showing for the other style.
Even if one of the style is attached -> article_title or article_container, its not being displayed.
Edit 2:
Even if I apply the style manually, it is not displayed like
<Text style={{fontSize: 25,alignSelf: 'center',marginBottom: 3,flex:2}} >{this.state.result.title}</Text>
I am navigating to this page from a parent which uses similar styles for a listview and it is showing there perfectly.
The problem seemed to be that I used flex property in styles without using ScrollView or ListView.
I would research more into that and update the answer.

Categories