React Native function to render Element dynamically doesn't render anything - react-native

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 => {

Related

How do I convert this class based component to a stateless component?

I am trying to render a table but I do not want to use a class based component.
How do I convert the following code into a const?
export default class Table extends Component {
renderRow() {
return (
<View style={{ flex: 1, alignSelf: 'stretch', flexDirection: 'row' }}>
<View style={{ flex: 1, alignSelf: 'stretch' }} /> { /* Edit these as they are your cells. You may even take parameters to display different data / react elements etc. */}
<View style={{ flex: 1, alignSelf: 'stretch' }} />
<View style={{ flex: 1, alignSelf: 'stretch' }} />
<View style={{ flex: 1, alignSelf: 'stretch' }} />
<View style={{ flex: 1, alignSelf: 'stretch' }} />
</View>
);
}
render() {
const data = [1, 2, 3, 4, 5];
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
{
data.map((datum) => { // This will render a row for each data element.
return this.renderRow();
})
}
</View>
);
}
}
This will be your functional component...
const Table = () => {
const data = [1, 2, 3, 4, 5];
const RenderRow = () => (
<View style={{ flex: 1, alignSelf: "stretch", flexDirection: "row" }}>
<View style={{ flex: 1, alignSelf: "stretch" }} />{" "}
{/* Edit these as they are your cells. You may even take parameters to display different data / react elements etc. */}
<View style={{ flex: 1, alignSelf: "stretch" }} />
<View style={{ flex: 1, alignSelf: "stretch" }} />
<View style={{ flex: 1, alignSelf: "stretch" }} />
<View style={{ flex: 1, alignSelf: "stretch" }} />
</View>
);
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
{data.map((datum,index) => (
<RenderRow key={index}/>
))}
</View>
);
};
export default Table;

Grid layout using flex In React Native

I am using flex to display some profile.
<View style={styles.flexContainer}>
<View style={styles.profileImgContainer} >
<Image style={styles.profileImg}/>
</View>
<View style={styles.name}>
<Markdown>{user.name}</Markdown>
</View>
</View>
const styles = StyleSheet.create({
flexContainer: {
flexDirection: 'row'
},
...,
});
I want to put Image in center of col1 using row1 and row2.
I want to put Markdown in col2 of row1.
My flex container should look like this.
col1 | col2 |
row1 |______|
| |
row2 ____|______|
How I can do this ?
Output:
Code:
<View style={styles.container}>
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={styles.col1}>
<Image source={{uri: 'https://www.deine-tierwelt.de/magazin/wp-content/uploads/sites/2/2013/10/Australian-Cattle-Dog-1000x570.jpg'}} style={{width: 100, height: 100}} />
</View>
<View style={styles.col2}>
<View style={styles.row1}>
<Text> Username </Text>
</View>
<View style={styles.row2}>
</View>
</View>
</View>
<View style={{flex: 1}} />
</View>
Stylesheet:
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
flexDirection: 'column',
padding: 8,
},
col1: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'gray'
},
col2: {
flex:1,
flexDirection: 'column'
},
row1: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
backgroundColor: 'lightgray'
},
row2: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
backgroundColor: 'darkgray'
}
Demo:
https://snack.expo.io/eoENHOHvq
Check below code
<View style={{ flex: 1, flexDirection: 'row' }}>
{/* column 1 */}
<View style={{ flex: 1, backgroundColor: 'green', justifyContent: 'center', alignItems: 'center' }}>
<Image
style={{ width: 50, height: 50 }}
source={{
uri: 'https://reactnative.dev/img/tiny_logo.png',
}}
/>
</View>
{/* column 2 */}
<View style={{ flex: 1 }}>
{/* row 1 */}
<View style={{ flex: 1, backgroundColor: 'red', justifyContent: 'center', alignItems: 'center' }}>
<Text>Hello</Text>
</View>
{/* row 2 */}
<View style={{ flex: 1, backgroundColor: 'yellow' }}>
</View>
</View>
</View>
Hope this helps you. Feel free for doubts.

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

Setting `backgroundColor` in style hides `View` component

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>

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