Setting `backgroundColor` in style hides `View` component - react-native

I have the following render() function in my component, it is replicating the look and feel of a table, but using flex in react-native.
<View>
<View key={ 'test' } style={{ flex: 1, flexDirection: 'row' }}>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col1</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col2</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col3</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col4</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col5</Text>
</View>
</View>
</View>
Which renders perfectly fine and as expected. However if I add backgroundColor: 'green' into the style of the top-most-level view, above, then the whole view is just gone. Can't even see it in the react-native inspector anymore.
Any idea why this is happening? Am I missing some gotcha, to do with not using background colors on nested View or something?
Edit: It is because there was a being wrapped around my component from the parent component, which also had to have flex: 1 explicitly set. Not sure why only adding backgroundColor causes this but there we go.

You have to set the style of the first view to flex: 1
<View style={{flex: 1}}>
<View key={ 'test' } style={{ flex: 1, flexDirection: 'row', backgroundColor: 'green' }}>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col1</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col2</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col3</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col4</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col5</Text>
</View>
</View>
</View>

You can try this, I think by setting the height and width to your parent view solve the problem
<View key={ 'test' } style={{ height: 500, width:500, flexDirection: 'row' }}>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col1</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col2</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col3</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col4</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Col5</Text>
</View>
</View>

Related

Problem positioning element to the bottom

I'm using native base as my app template and I've been trying to position two button elements above the footer using only flex. Here is how the buttons are positioned currently.
I tried doing justifyContent: flex-end / space-between but the buttons remains far away from the footer.
<Container>
<Header>
<MainHeader />
</Header>
<Content>
<View style={{flex: 1, justifyContent: 'center'}} >
<View style={{ borderBottomColor: 'black', borderBottomWidth: 1, height: 50 }}>
<View style={{ flexDirection: 'row' }}>
<View style={{ flex: 1, alignSelf: 'center' }}>
<Text>Name</Text>
</View>
<View style={{ flex: 1, alignSelf: 'center' }}>
<Text>Sales</Text>
</View>
<View style={{ flex: 1, alignSelf: 'center' }}>
<Text>Commission</Text>
</View>
<View style={{ flex: 1, alignSelf: 'center' }}>
<Text>Payout</Text>
</View>
<View style={{ flex: 1, alignSelf: 'center' }}>
<Text>Profit</Text>
</View>
</View>
</View>
{this.renderRow()}
<View style={{ flexDirection: 'column', justifyContent: 'space-between' }} >
<View style={{ flexDirection: 'row', alignSelf: 'stretch', height: 50, justifyContent: 'space-between' }} >
<View style={{flex:1, alignSelf: 'center'}}>
<Button onPress={() => this.share(this.state.response)} title="Share"></Button>
</View>
<View style={{flex:1, alignSelf: 'center'}}>
<Button onPress={() => this.share(this.state.response)} title="Share"></Button>
</View>
</View>
</View>
</View>
</Content>
<Footer>
<MainFooter />
</Footer>
</Container>
I want the share buttons to be at the bottom of the page above the footer.
The reason is basically because everything is inside content which is basically a scrollview. You can't send something to the end of scrollview as it is parent.
You can access the prop of contentContainerStyle of content from native base and then give it style of justifyConent & alignItens -> flex-end.
I hope it'll work.
This will help you.

React Native function to render Element dynamically doesn't render anything

I wrote a function to render views dynamically based on an object. But the function does not render any views when invoked.
I've tried adding and taking away render() in my function but it doesn't seem to work.
var arr = this.state.response;
Object.keys(arr).map(key => {
console.log(arr[key]);
return (
<View style={{ flex: 1, alignSelf: 'stretch', flexDirection: 'row' }}>
<View style={{ flex: 1, alignSelf: 'stretch'}}>
<Text>{key}</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch'}}>
<Text>{arr[key].sales}</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch'}}>
<Text>{arr[key].sales}</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch'}}>
<Text>{arr[key].sales}</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch'}}>
<Text>{arr[key].sales}</Text>
</View>
</View>
)
})
}
And the renderRow function is called in the view like this
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<View style={{ flex: 1, alignSelf: 'stretch', flexDirection: 'row' }}>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Name</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Sales</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Commission</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Payout</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text>Profit</Text>
</View>
</View>
{this.renderRow()}
</View>
);
}
change renderRow function
renderRow = () => {
const arr = this.state.response;
return Object.keys(arr).map(key =>
<View style={{ flex: 1, alignSelf: 'stretch', flexDirection: 'row' }}>
<View style={{ flex: 1, alignSelf: 'stretch'}}>
<Text>{key}</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch'}}>
<Text>{arr[key].sales}</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch'}}>
<Text>{arr[key].sales}</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch'}}>
<Text>{arr[key].sales}</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch'}}>
<Text>{arr[key].sales}</Text>
</View>
</View>
}
Your renderRow function does not return anything...
return Object.keys(arr).map(key => {

Why backgroundColor doesn't work with View in React Native?

I'm trying to make a top menu and colorize it, but backgroudColor property doesn't work.
How the app looks now
<View>
<View style={{
flex: 1,
height: 50,
flexDirection: 'row',
justifyContent: 'space-between',
backgroundColor: 'skyblue'
}}>
<View style={{flex: 1, backgroundColor: 'skyblue'}}><Text style={style.upMenu.text}>H</Text></View>
<View style={{flex: 1, backgroundColor: 'skyblue'}}><Text style={style.upMenu.text}>Plugins</Text></View>
<View style={{flex: 1, backgroundColor: 'skyblue'}}><Text style={style.upMenu.text}>Remote</Text></View>
<View style={{flex: 1, backgroundColor: 'skyblue'}}><Text style={style.upMenu.text}>P</Text></View>
</View>
</View>
Solved
Thanks a lot, your answers both are very useful!
Give prop flex:1 to the parent view style.
<View style={{flex:1}}>
.....Child Views
</View>
use the code below,
<View style={{ flex: 1 }}>
<View
style={{
flex: 1,
height: 50,
flexDirection: "row",
justifyContent: "space-between",
backgroundColor: "#87ceeb",
maxHeight: 20
}}
>
<View style={{ flex: 1, backgroundColor: "#87ceeb" }}>
<Text style={style.upMenu.text}>H</Text>
</View>
<View style={{ flex: 1, backgroundColor: "#87ceeb" }}>
<Text style={style.upMenu.text}>Plugins</Text>
</View>
<View style={{ flex: 1, backgroundColor: "#87ceeb" }}>
<Text style={style.upMenu.text}>Remote</Text>
</View>
<View style={{ flex: 1, backgroundColor: "#87ceeb" }}>
<Text style={style.upMenu.text}>P</Text>
</View>
</View>
</View>
to get the required header height use the maxHeight to change it

How to vertically stretch two Views that are in a column formation - React Native Flex?

I have this view, where there are two Views in a column:
<View style={styles.container}>
<View style={styles.content}>
<View style={{backgroundColor: 'orange'}}>
<Text>Test</Text>
</View>
<View style={{backgroundColor: 'yellow'}}>
<Text>Test2</Text>
</View>
</View>
</View>
This is my Styles:
container: {
flexDirection: 'row',
backgroundColor: 'white',
justifyContent:'center',
alignItems:'center',
height: 80,
margin: 8,
},
content: {
flex:1,
alignItems: 'stretch',
flexDirection: 'column',
},
Here is a ScreenShot of what it looks with the above code.
How can I get the orange and yellow View to expand vertically equally, without manually defining the height for each of them?
The Text inside should be centered, but left-aligned.
Add flex: 1 to each cell to make them expand and add justifyContent: 'center' to make the text vertically centered. Like this:
<View style={styles.container}>
<View style={styles.content}>
<View style={{ backgroundColor: 'orange', flex: 1, justifyContent: 'center' }}>
<Text>Test</Text>
</View>
<View style={{ backgroundColor: 'yellow', flex: 1, justifyContent: 'center' }}>
<Text>Test2</Text>
</View>
</View>
</View>

Loading View programatically takes too long

I'm trying to create a table from an array. However, loading it takes a bit too long. Is there a way to speed it up?
allData contains about 250 arrays
Function to generate rows
renderRow = (num,one,three,four,five) => {
return (
<View key={num} style={{ flex: 1, alignSelf: 'stretch', flexDirection: 'row' }}>
<View style={{ flex: 0.5, alignSelf: 'stretch' }}>
<Text style={{ textAlign: 'center' }}>{num}</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text style={{ textAlign: 'center' }}>{one}</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text style={{ textAlign: 'center' }}>{three}</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text style={{ textAlign: 'center' }}>{four}</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text style={{ textAlign: 'center' }}>{five}</Text>
</View>
</View>
);
}
Displaying the table is what takes about 5 seconds
DrawSchedule = () => {
var allData = this.state.allData;
var Rows = [];
var Table = [];
allData.map((datum) => {
Rows.push(this.renderRow(datum[0],datum[1],datum[3],datum[4],datum[5]));
})
Table = [];
Table.push(
<View key="head" style={styles.tableContainer}>
<View style={{ flex: 1, alignSelf: 'stretch', flexDirection: 'row' }}>
<View style={{ flex: 0.5, alignSelf: 'stretch' }}>
<Text style={{ textAlign: 'center' }}>Title A</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text style={{ textAlign: 'center' }}>Title B</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text style={{ textAlign: 'center' }}>Title C</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text style={{ textAlign: 'center' }}>Title D</Text>
</View>
<View style={{ flex: 1, alignSelf: 'stretch' }}>
<Text style={{ textAlign: 'center' }}>Title E</Text>
</View>
</View>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
{Rows}
</View>
</View>
)
this.state.Table = Table;
this.setState({Table: this.state.Table});
}
render() {
return (
<View style={styles.container}>
<ScrollView>
<Button
style={styles.loginButton}
onPress={this.DrawSchedule}
title="Load Data"
/>
{this.state.Table}
</ScrollView>
</View>
);
}
Use FlatList to render large list for performance:
import { FlatList } from 'react-native';
render() {
return (
<FlatList
data={this.state.data}
keyExtractor={(item) => ....}
renderItem={({ item }) => (
<View>
...
</View>
)}
/>
);
}
Please read FlatList