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
Related
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.
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 => {
Im trying to make this view with a bubble image in the margin between the left of the screen and the larger square images like the picture below
but my bubble will not stay in line with the view and
I get this
`
const Recipe = ({ name, durationLabel, numberOfServings, handlePress, handlePush }) => (
<View styles={{flexDirection: 'row'}}>
<TouchableHighlight onPress={handlePush}>
<View syle={{ justifyContent:'center'}}>
<Image
source={require("app/assets/icons/bubbleOff.png")}
style={{justifyContent:'center'}}
/>
</View>
</TouchableHighlight>
<TouchableHighlight onPress={handlePress}>
<View style={styles.recipeTile}>
<Image
source={require("app/assets/cheesecake.png")}
style={styles.recipeImage}
/>
<View style={styles.recipeInfo}>
<View style={styles.recipeNameRow}>
<Text style={styles.recipeName}>{name}</Text>
<Image
style={{ marginRight: 10 }}
source={require("app/assets/icons/heart.png")}
/>
</View>
<View style={styles.recipeStatsRow}>
<Text style={styles.recipeStats}>
{durationLabel}
{' '}
| Serves
{' '}
{numberOfServings}
</Text>
</View>
</View>
</View>
</TouchableHighlight>
</View>
);`
my styles
`
recipeTile: {
flexDirection: "row",
flex: 1,
margin: 10,
backgroundColor: "white",
marginLeft:60,
},
recipeImage: {
width: 100,
height: 100
},`
Use justifyContent: 'center' and alignItems: 'center' to align the image center.
const Recipe = ({
name,
durationLabel,
numberOfServings,
handlePress,
handlePush,
}) => (
<TouchableHighlight onPress={handlePush}>
<View style={{ flexDirection: 'row' }}>
<View style={{ flex: 0, justifyContent: 'center', alignItems: 'center', marginLeft: 5, marginRight: 5 }}>
<Image
source={require('assets/bubbleOff.png')}
style={{ height: 20, width: 20 }}
/>
</View>
<View style={{ flexDirection: 'row', flex: 1, backgroundColor: '#FFF' }}>
<View style={{ flex: 0 }}>
<Image
source={require('assets/cheesecake.png')}
style={styles.recipeImage}
/>
</View>
<View style={{ flex: 1 }}>
<Text style={styles.recipeName}>{name}</Text>
<Text style={styles.recipeStats}>
{durationLabel} | Serves {numberOfServings}
</Text>
</View>
<Image
style={{
marginRight: 10,
height: 20,
width: 20,
position: 'absolute',
right: -20,
top: 30,
}}
source={require('assets/heart.png')}
/>
</View>
</View>
</TouchableHighlight>
);
Working demo
I am still learning about react native especially flexbox. So I have a TouchableOpacity that have some child components on it, like this:
And the problem is I can't move that arrow icon to the middle right of TouchableOpacity. I try with
justifyContent: 'center', alignItems: 'flex-end' But nothing happened. Here is my code :
<TouchableOpacity onPress={this.onRowPress}>
<View style={{ padding: 5 }}>
<CardSection style={{ flex: 1 }}>
<Icons name="monitor" size={50} style={{ paddingLeft: 10 }} />
<View style={{ flexDirection: 'column' }}>
<Text style={styles.channelStyle}>
{item.nama}
</Text>
<Text
style={
[item.status === 'Online' ? onlineTextStyle : offlineTextStyle]
}
>
{item.status}
</Text>
</View>
<Icons name="arrow-right" size={50} style={styles.arrowIconStyle} />
</CardSection>
</View>
</TouchableOpacity>
And this is the style:
const styles = {
channelStyle: {
fontSize: 25,
paddingLeft: 30
},
onlineTextStyle: {
paddingLeft: 30,
color: 'green'
},
offlineTextStyle: {
paddingLeft: 30,
color: 'red'
},
footerTextStyle: {
flex: 1,
textAlign: 'center',
color: '#fff',
padding: 5,
fontSize: 18
},
arrowIconStyle: {
justifyContent: 'center',
alignItems: 'flex-end'
}
};
Is there something I missed?
Could you try the following and let me know how it goes?
// 1. Add flexDirection row here.
<CardSection style={{ flex: 1, flexDirection: 'row' }}>
...code...
// 2. Add alignSelf here.
<Icons name="arrow-right" size={50} style={[styles.arrowIconStyle, {alignSelf: 'flex-end'}]} />
</CardSection>
If that doesn't work, try not doing the previous step 2 and instead try this.
...code...
<Icons name="arrow-right" size={50} style={styles.arrowIconStyle} />
const styles = {
...code...
arrowIconStyle: {
justifyContent: 'center',
alignSelf: 'flex-end'
}
};
Update
<TouchableOpacity onPress={this.onRowPress}>
<View style={{ padding: 5 }}>
<CardSection style={{flex: 1, flexDirection: 'row', justifyContent: 'space-between'}}>
<View style={{ flex: 1 }}>
<Icons name="monitor" size={50} style={{ paddingLeft: 10 }} />
<View style={{ flexDirection: 'column' }}>
<Text style={styles.channelStyle}>
{item.nama}
</Text>
<Text
style={[item.status === 'Online' ? onlineTextStyle : offlineTextStyle]}>
{item.status}
</Text>
</View>
</View>
<Icons name="arrow-right" size={50} style={styles.arrowIconStyle} />
</CardSection>
</View>
</TouchableOpacity>
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>