here i use flatlist grid inside scrollview, the problem is the last row of the grid didn't display the full height of the content, i don't know where the problem is.
note: i use native-base component
const [data, setData] = useState([
{ id: 1, title: "DA’s Backyard" },
{ id: 2, title: "KC’s Backyard" },
{ id: 3, title: "LA’s Backyard" },
{ id: 4, title: "KP’s Backyard" },
{ id: 5, title: "LA’s Backyard" },
{ id: 6, title: "KP’s Backyard" },
]);
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={{ width: "100%", alignItems: "center" }}
>
<Stack flexWrap={"wrap"} justifyContent="center">
<SelectBox />
<FlatList
mt={"4"}
showsVerticalScrollIndicator={false}
data={data}
keyExtractor={(item, index) => index}
numColumns={2}
renderItem={(data, index) => {
return <PortfolioCard />;
}}
/>
</Stack>
</ScrollView>
Add this please to flat list
<FlatList
mt={"4"}
showsVerticalScrollIndicator={false}
data={data}
keyExtractor={(item, index) => index}
numColumns={2}
renderItem={(data, index) => {
return <PortfolioCard />;
}}
contentContainerStyle={{paddingBottom:50}} // add this
/>
Related
I have screen with 3 different Lists, all lists have some custom header/footer and Lists contain big amount of data, so my question is - is there any performance issue with FlatList inside of SectionList?
This is rough example what i want to do
const App = () => {
const renderItem = ({item, section, index}) => {
switch (section.type) {
case 'LIST_1':
return (
<View>
<Text>Some custom set of components</Text>
<FlatList
data={section.items}
renderItem={({item}) => (
<View
style={{
padding: 20,
margin: 10,
backgroundColor: 'blue',
}}>
<Text>{item.title}</Text>
</View>
)}
keyExtractor={item => item.id}
/>
</View>
);
case 'LIST_2':
return (
<View>
<Text>Some custom set of components</Text>
<FlatList
data={section.items}
renderItem={({item}) => (
<View
style={{
padding: 20,
margin: 10,
backgroundColor: 'red',
}}>
<Text>{item.count}</Text>
</View>
)}
keyExtractor={item => item.id}
/>
</View>
);
case 'LIST_3':
return (
<View>
<Text>Some custom set of components</Text>
<FlatList
data={section.items}
renderItem={({item}) => (
<View
style={{
padding: 20,
margin: 10,
backgroundColor: 'blue',
}}>
<Text>{item.score}</Text>
</View>
)}
keyExtractor={item => item.id}
/>
</View>
);
}
};
const sections = [
{
type: 'LIST_1',
data: [1],
items: Array.from(Array(50)).map((el, i) => ({
id: i + 1,
title: i + 1,
})),
},
{
type: 'LIST_2',
data: [2],
items: Array.from(Array(50)).map((el, i) => ({
id: i + 1,
count: i + 1,
})),
},
{
type: 'LIST_3',
data: [3],
items: Array.from(Array(50)).map((el, i) => ({
id: i + 1,
score: i + 1,
})),
},
];
return (
<SafeAreaView>
<SectionList
sections={sections}
keyExtractor={item => item}
renderItem={renderItem}
/>
</SafeAreaView>
);
};
If this is not optimal solution and ScrollView takes a lot of time to render, Can you guide me what is better?
Your example can be achieved simply by using SectionList.
// Here we define section objects. I arbitrarily added title, footer and style.
const DATA = [
{
title: 'Section 1 header',
footer: 'Section 1 footer',
data: [...Array(3).keys()],
style: { backgroundColor: 'red' },
},
{
title: 'Section 2 header',
footer: 'Section 2 footer',
data: [...Array(3).keys()],
style: { backgroundColor: 'blue' },
},
{
title: 'Section 3 header',
footer: 'Section 3 footer',
data: [...Array(3).keys()],
style: { backgroundColor: 'yellow' },
},
]
// renderItem gets passed an object with item, section, index and separator keys. I'm using item and section to access my own section style.
const Item = ({ item, sectionStyle }) => (
<View style={[styles.item, sectionStyle]}>
<Text style={styles.title}>{item}</Text>
</View>
)
// Use renderSectionHeader and renderSectionFooter props to add, respectively, header and footer.
const App = () => (
<SafeAreaView style={styles.container}>
<SectionList
sections={DATA}
keyExtractor={(item, index) => item + index}
renderItem={({ item, section }) => <Item item={item} sectionStyle={section.style} />}
renderSectionHeader={({ section: { title } }) => <Text style={styles.header}>{title}</Text>}
renderSectionFooter={({ section: { footer } }) => <Text style={styles.header}>{footer}</Text>}
/>
</SafeAreaView>
)
And to answer your original question, you might run into performance issues with react-natives list components, it depends on many factors, including your data and rendered components.
You can read more on the topic here:
https://reactnative.dev/docs/optimizing-flatlist-configuration
Flatlist rendered 4 rows but the data variable only have 3 objects
Array items:
const data = [
{ type: 250, amount: 2, points: 150 },
{ type: 250, amount: 2, points: 150 },
{ type: 250, amount: 2, points: 150 },
];
My flatlist:
<FlatList
style={styles.list}
data={data}
keyExtractor={(item, index) => index.toString()}
contentContainerStyle={{
paddingTop: pxToPercentage(8),
}}
renderItem={({ item }) => {
return (
<View style={styles.rowStyle}>
<Text style={styles.typeStyle}>{item?.type}</Text>
<Text>{item?.amount}</Text>
<Text style={styles.pointStyle}>{item?.points}</Text>
</View>
);
}}
/>
Edit:
There is no error here, but a blank view between flatlist and footer how can i remove it
There is no Error, I ran also the same code in my project, and this is working fine.
import React from "react";
import { FlatList, StyleSheet, Text, View } from "react-native";
export default function App() {
const data = [
{ type: 250, amount: 2, points: 150 },
{ type: 250, amount: 2, points: 150 },
{ type: 250, amount: 2, points: 150 },
];
return (
<View>
<FlatList
data={data}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => {
return (
<View style={{ backgroundColor: "grey", margin: "10px" }}>
<Text>
{item?.type} | {item?.amount} | {item?.points}
</Text>
</View>
);
}}
/>
</View>
);
}
You can see in the picture, this is the output of the above code, there are only three lists, as I change the background color to grey.
I need to create a screen Catalog(Categories and Products).
I'm using SectionList from React Native in order to achive this.
I need to make that Categories component stick on the top when you scroll product lists.
Is there any library that could help me with this Catalog screen ?
Please look at the image here..
import React from "react";
import { View, StyleSheet, SectionList } from "react-native";
import Text from "../Text";
const DATA = [
{
title: "Main dishes",
data: ["Pizza", "Burger", "Risotto"],
},
{
title: "Sides",
data: ["French Fries", "Onion Rings", "Fried Shrimps"],
},
{
title: "Drinks",
data: ["Water", "Coke", "Beer"],
},
{
title: "Desserts",
data: ["Cheese Cake", "Ice Cream"],
},
];
const TabCategories = () => (
<View>
<Text>Horizontal list of categories</Text>
</View>
);
const Item = ({ title }) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
const TestSectionList = (props) => {
return (
<View style={styles.container}>
<Text style={styles.SRC}>Some React Component</Text>
<SectionList
sections={DATA}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => <Item title={item} />}
renderSectionHeader={({ section: { title } }) => (
<Text style={styles.header}>{title}</Text>
)}
StickyHeaderComponent={TabCategories}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {},
SRC: {
fontWeight: "bold",
borderWidth: 1,
borderColor: "#fff",
padding: 10,
},
item: {
padding: 30,
},
header: {
fontWeight: "bold",
fontSize: 20,
},
});
export default TestSectionList;
stickySectionHeadersEnabled
Makes section headers stick to the top of the screen until the next one pushes it up
ListHeaderComponent
Rendered at the very beginning of the list
renderSectionHeader
Rendered at the top of each SECTION
I think this should do:
<SectionList
sections={DATA}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => <Item title={item} />}
ListHeaderComponent={({ section: { title } }) => (
<Text style={styles.header}>{title}</Text>
)}
renderSectionHeader={TabCategories}
stickySectionHeadersEnabled
/>
You can try this library react-native-tabs-section-list
https://github.com/bogoslavskiy/react-native-tabs-section-list
If you are talking about react-native-section-list, it inherits ScrollView props, you can check in the docs, in props section, so it has stickyHeaderComponent prop which should be exactly what you want.
i have a flatList that renders a component with some props, but the renderItem returns me 'undefined'. I´m new to react-native and I cant´t find a solution. Thanks
edit:
Is it possible that the styles I used in 'posts.js' may affect the flatList render?
Feed.js:
export default function Feed() {
const Posts = [
{ id: 1, title: "eu", photoDesc: 'eu' },
{ id: 2, title: "me", photoDesc: 'me' }
]
console.log;
return (
<FlatList
keyExtractor={props => props.id}
data={Posts}
renderItem={({ item }) => <FeedPosts title={`${item.title}`} photoDesc={`${item.photoDesc}`} ></FeedPosts>}
>
</FlatList>
);
}
Posts.js:
export default function FeedPosts(props) {
return (
<Container>
<Header>
<TouchableOpacity>
<FontAwesome5 name='bell' size={40} style={{ marginLeft: 10 }}></FontAwesome5>
</TouchableOpacity>
<TouchableOpacity>
<Ionicons name='add-circle' size={40} style={{ marginRight: 5 }}></Ionicons>
</TouchableOpacity>
</Header>
<Body>
<Time>15/12/2021 as 17:42pm</Time>
<User>
<Icon source={require('../../assets/vibe.jpg')}></Icon>
<Description>{props.title}</Description>
</User>
<Content>
<PetPhoto source={props.postImg}></PetPhoto>
</Content>
<ContentDesc >
<PhotoDesc> {props.photoDesc}</PhotoDesc>
</ContentDesc>
<Bottom>
<Comment title="Comment" placeholder="Escrever Comentário"></Comment>
</Bottom>
<Buttons></Buttons>
</Body>
</Container>
);
}
Your variable Posts contains an array of React components. Instead, it should contain an array of data that you transform into components.
So your Posts should look more like this:
const Posts = [
{title: "My title", photoDesc: "Desc"},
{title: "My title2", photoDesc: "Desc2"},
{title: "My title3", photoDesc: "Desc3"}
]
Here's an example (straight from the React Native documentation) of how this works in context:
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
];
const Item = ({ title }) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
const App = () => {
const renderItem = ({ item }) => (
<Item title={item.title} />
);
return (
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
}
(https://reactnative.dev/docs/flatlist)
You can see in the above example that DATA is an array of objects, which gets transformed with the function renderItem into components. Very similar to your use case.
I have a map which loop all items in the products object and output each new items, What i want is to remove the red line under the "product 003", which is the last item.
Image
const App = () => (
<View style={styles.container}>
{products.map((product, index) => (
<ShoppingList key={index} title={product.title} price={product.price} />
))}
</View>
);
const ShoppingList = props => {
return (
<View style={styles.line}>
<Text>{props.title}</Text>
<Text>{props.price}</Text>
</View>
);
};
const products = [
{
title: 'Product 001',
price: '100000',
},
{
title: 'Product 002',
price: '20000',
},
{
title: 'Product 003',
price: '10000',
},
];
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 24,
},
line: {
padding: 4,
borderBottomColor: 'red',
borderBottomWidth: StyleSheet.hairlineWidth,
},
});
Either use the index provided in the .map loop
{products.map((product, index) => (
(index === products.length) ? <ItemWithoutHorizontalLine /> : <ItemWithHorizontalLine />
))}
or use a VirtualizedList (or any of the child components of VirtualizedList e.g., FlatList) and provide a ItemSeparatorComponent
<FlatList
...
ItemSeparatorComponent={this.renderSeparator}
</FlatList>