FlatList showing 10 items until render() is called - reactjs

I have a FlatList component that renders 20 items. When I load up the page in React Native, my FlatList shows 10 items. Once a render has occurred, the next 10 are loaded.
<FlatList
data={data}
keyExtractor={(item, i) => String(i)}
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.boardList}
renderItem={({ item, index }) => (
<Item {...item}/>
)}
/>
data is simply an Array of JSON objects.

You should set following properties
initialNumToRender={20}
maxToRenderPerBatch={20}
As the default is 10

It may be better to use ScrollView and .map(() = > {}) ?

Add style={{ flex: 1 }} in FlatList

Related

How to Limit render element Flat List and add more content in React Native

I want like that flatlist render only 5 checkbox items and then when I click to +5 more button it will show 5 more checkbox list.In this all checkbox list appearing but i want only five
Please help me how to achieve that
Thanks in advance
const renderResourceList = renderData => {
return (
<FlatList
data={renderData}
initialNumToRender={5}
maxToRenderPerBatch={5}
pagingEnabled={true}
nestedScrollEnabled={true}
renderItem={({item}) => (
<View style={styles.card}>
<TouchableOpacity
onPress={() => {
if(resourceTypeArray.includes(item)){
setResourceTypeArray(currentList => {
return currentList.filter(items => items !== item);
});
}
else{
setResourceTypeArray(currentList => [
...currentList,
item
]);
}
onSetResourceType(item);
}}
style={styles.modalBtn}>
<Icon
name={
resourceTypeArray.includes(item) ? 'checkbox-marked' : 'checkbox-blank-outline'
}
size={18}
color="#353C3C"
style={{bottom: -1}}
/>
<View style={styles.textWrapper}>
<Text style={styles.modalText}>{item.charAt(0)}
{item.toLowerCase().slice(1).replace(/_/g, ' ')}</Text>
</View>
</TouchableOpacity>
</View>
)}
/>
);
};
I tried but this not working
I used a package called flatlist-react to handle this for me. A decent tutorial for this can be found here.
With this package, you can directly specify and limit the items rendered with the limit prop. Here is an example:
<FlatList
limit="2,-2"
list={people}
renderItem={Person}
/>
If you keep track of the limit prop variables using state, you can dynamically change these values when you click 5+ more in order to render whatever part of your data you would like.

React Native FlatList: how to reset scroll position

I have a horizontal FlatList in my React Native iOS app. At the bottom of the screen, the FlatList is displayed with 5 items. If you click on the last item (scrolled all the way to the right), the screen will refresh and the FlatList will remain scrolled to the right. How can I get the FlatList to always reset the scroll position (to scroll from the beginning) when the screen changes?
Edit: I have a feeling that my screen is not actually "refreshing" but rather merely changing the data shown on the screen. In this case I may need to trigger a refresh of the screen somehow to cause the FlatList to reset the scroll position? Any help would be greatly appreciated!
const HorizontalScroll = ({items, handlePress}) => {
const renderItem = ({item}) => {
const itemData = { color: item.color, title: item.title };
return <HorizontalItem itemData={itemData} handlePress={handlePress} />;
};
return (
<View style={styles.container}>
<FlatList
data={items}
renderItem={renderItem}
horizontal={true}
numColumns={1}
key={(item) => item.id}
initialNumToRender={5}
scrollToIndex={0}
ItemSeparatorComponent={() => <View style={{width: 8}} />}>
</FlatList>
</View>
);
};
I solved this problem by forcing a refresh of the component. Specifically, I added a key prop to my component so that every time the key value changes, it remounts the component. This causes the FlatList to reset the scroll position to the beginning.
<View key={items[0].title}>
{content}
</View>

FlatList rendering is heavy for big data set

In my application I have a FlatList with dataset of 100 items in it. Each item has a complex UI and I noticed that it's taking a heavy toll on performance. The page that has the list takes up to 5 seconds to load.
I noticed that the moment the component is rendered for the first time, the renderItem function of the FlatList is also called for each and every item in my data set, I also noticed that it also happens if there any other setState change for other stuff on that page. Is there a way to prevent this re-rendering of the flat list or at least to re-render only the visible items - just like with Recycle with in native Android?
How can I only render the visible items when the component first appears?
I tried to use initialNumToRender and maxToRenderPerBatch but neither have worked.
Here is an example of the code:
const Item = ({ title }) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
const App = () => {
const [text, setText] = React.useState('')
const renderItem = ({ item }) => {
console.log("Render Item")
return (<Item title={item.title} />)
};
return (
<SafeAreaView style={styles.container}>
<TextInput
value={text}
onChangeText={(val) => setText(val)}
/>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
initialNumToRender={6}
maxToRenderPerBatch={6}
/>
</SafeAreaView>
);
}
If I try to type something in TextInput the whole list re-renders but nothing in the list has changed.. how can I prevent this?

React Native - stickyHeaderIndices not working for SectionList

I am trying to make some header to stick to the top of the SectionList but it seems like the stickyHeaderIndices={[0]} doesn't work as expected. This is the section list:
<SectionList
ref={(ref) => (productsSectionListRef = ref)}
stickyHeaderIndices={[0]}
ListHeaderComponent={_renderHeader()}
contentContainerStyle={[style.products_container]}
sections={productListSections}
renderItem={({item, section}: {item: string; section: any}) => {
return _renderProduct(item);
}}
stickySectionHeadersEnabled={false}
renderSectionHeader={({section}) => {
return _renderProductHeader(section.title);
}}
keyExtractor={(item) => item}
showsVerticalScrollIndicator={false}
viewabilityConfig={{
itemVisiblePercentThreshold: 50,
}}
onViewableItemsChanged={_onViewableItemsChanged}
bounces={false}
scrollEventThrottle={4}
initialNumToRender={productListSections.length}
scrollEnabled={scrollEnabled}
removeClippedSubviews={true}/>
I tryed to put the header outside the section list but the header it's bigger and I cannot scroll inside of that header component.
stickyHeaderIndices={[0]}
will make first item in flatlist sticky to the top
if you change to
stickyHeaderIndices={[5]}
the 4th item will stick to top after the item reached to the top when scrolled
item in
ListHeaderComponent={_renderHeader()}
will be on top of the flatlist but not act as item inside flatlist its independent

Dynamically changing number of columns in React Native Flat List

I have a FlatList where I want to change the number of columns based on orientation. However, I get the red screen when I do this. As per the red screen error message, I'm not quite sure how I should be changing the key prop. Any help is appreciated.
// dynamically changing number of columns
const numCols = orientation === constants.PORTRAIT ? 3 : 8
<FlatList
keyExtractor={(_, i) => i}
numColumns={numCols} // assigning the number of columns
horizontal={false}
renderItem={({ item }) => <ListItem imageUrl={item.url} />}
/>}
From the documentation, looks like you should do something like this
key={(this.state.horizontal ? 'h' : 'v')}
I did it using key
numColumns = {this.state.columnCount}
key={this.state.columnCount}
Pass a changing value to the FlatList itself. It has nothing to do with the keyExtractor or the key attrbibute in renderItem methods:
<FlatList key={changingValue} .. />
should solve it.
In Hooks
const [numCols, setColumnNo] = useState(0);
<FlatList
key={numCols}
numColumns={numCols}
...
/>
<FlatList
data={props.localFolders}
style={{ width: "100%" }}
numColumns={4}
key={4}
renderItem={({ item }) => <LocalFolder {...item} />}
keyExtractor={(item) => item.id.toString()}
/>
works for me
I think the message is very clear. You need to define different keys for portrait/landscape if you want to change the number of columns to force a fresh re-render. Try concatenating the numCols value to the index in your keyExtractor.
If you need to make your app responsive when is landscape mode, try this:
const {height, width} = useWindowDimensions();
const isLandscape = width > height;
<FlatList
numColumns={Number(isLandscape) + 1}
keyExtractor={item => item.id}
key={Number(isLandscape)}
...
This will convert boolean into number.
Note useWindowDimensions is imported from react-native.

Resources