I'm teaching myself React and I'm trying to use a FlatList. For some reason my list is not rendering as expected. I have some list "ListItem" objects, and when I simply render them in a View, they work fine:
Here is the ListItem:
import { View, Text, Image, StyleSheet } from "react-native";
interface Props {
title: string;
subtitle: string;
}
function ListItem({ title, subtitle }: Props) {
return (
<View style={styles.itemStyle}>
<Image
style={styles.imageStyle}
source={require("../assets/user.png")}
></Image>
<View>
<Text style={styles.titleStyle}>{title}</Text>
<Text style={styles.subtitleStyle}>{subtitle}</Text>
</View>
</View>
);
}
export default ListItem;
const styles = StyleSheet.create({
itemStyle: {
flexDirection: "row",
backgroundColor: "lightblue",
width: "80%",
height: "10%",
borderRadius: 10,
margin: 5,
alignItems: "center", // aling vertically
paddingLeft: 10,
},
imageStyle: {
width: 55,
height: 55,
},
titleStyle: {
fontSize: 20,
fontFamily: "Avenir",
fontWeight: "600",
paddingLeft: 10,
},
subtitleStyle: {
fontSize: 15,
fontFamily: "Avenir",
fontWeight: "400",
paddingLeft: 10,
color: "grey",
},
});
And here is the View in which I render them (not using a FlatList yet):
import {
SafeAreaView,
} from "react-native";
import Constants from "expo-constants";
import ListItem from "./ListItem";
function FlatListScreen() {
return (
<SafeAreaView
style={{
flex: 1,
alignItems: "center",
backgroundColor: "#E2F0FB",
paddingTop: Constants.statusBarHeight,
}}
>
<ListItem title="William I" subtitle="Changed England forever"></ListItem>
<ListItem
title="Henry VIII"
subtitle="Weird dude with lots of wives"
></ListItem>
<ListItem title="Richard I" subtitle="Known as the Lionheart"></ListItem>
</SafeAreaView>
);
}
The result is as I expect:
But as soon as I try to show this in a FlatList, it gets all buggy and distorted. Here is the code:
import { SafeAreaView, FlatList, View } from "react-native";
import Constants from "expo-constants";
import ListItem from "./ListItem";
function FlatListScreen() {
// Prepare array data for FlatList
const items = [
{
id: 1,
title: "William I",
subtitle: "Changed England forever",
},
{
id: 2,
title: "Henry VIII",
subtitle: "Weird dude with lots of wives",
},
{
id: 3,
title: "Richard I",
subtitle: "Known as the Lionheart",
},
];
return (
<SafeAreaView
style={{
flex: 1,
alignItems: "center",
backgroundColor: "#E2F0FB",
paddingTop: Constants.statusBarHeight,
}}
>
<FlatList
data={items}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => (
<ListItem title={item.title} subtitle={item.subtitle}></ListItem>
)}
></FlatList>
</SafeAreaView>
);
}
export default FlatListScreen;
But this is how it shows when using the FlatList:
It is very basic code so I don't understand why the items are getting all squished and distorted. Please help.
I looked through your code I noticed where the bug might possibly be lurking. It looks like the height
style property is the culprit here. The height: 20%
is setting the height of your ListItem component to 20% of the FlatList
height and that is why your ListItems
look compressed. Also, I have taken out the width: 80%
too so that it can take a 100% width of the FlatList component. I have made a change to your code and did some little refactoring as well:
import { View, Text, Image, StyleSheet } from "react-native";
function ListItem({ title, subtitle }: Props) {
return (
<View style={styles.itemStyle}>
<Image
style={styles.imageStyle}
source={require("../assets/user.png")}
/>
<View>
<Text style={styles.titleStyle}>{title}</Text>
<Text style={styles.subtitleStyle}>{subtitle}</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
itemStyle: {
flexDirection: "row",
backgroundColor: "lightblue",
borderRadius: 10,
margin: 5,
alignItems: "center", // aling vertically
paddingLeft: 10,
},
imageStyle: {
width: 55,
height: 55,
},
titleStyle: {
fontSize: 20,
fontFamily: "Avenir",
fontWeight: "600",
paddingLeft: 10,
},
subtitleStyle: {
fontSize: 15,
fontFamily: "Avenir",
fontWeight: "400",
paddingLeft: 10,
color: "grey",
},
});
import { FlatList } from "react-native";
function FlatListScreen() {
// Prepare array data for FlatList
const renderItem = ({ item }: { item: Props }) => {
return <ListItem title={item.title} subtitle={item.subtitle} />;
};
return (
<FlatList
data={items}
keyExtractor={(item) => item.id.toString()}
renderItem={renderItem}
/>
);
}
export default FlatListScreen;