When using a FlatList Component in react native I need to know when all the visible items have been rendered.
I am providing data
and the renderItem
when I get the componentDidMount
I can see the FlatList there but because FlatList Component asynchronously renders each item they only show up after on componentDidUpdate
. Also, this could (and probably will) include off-view items.
I would like to know if there is someone out there that has found a possible way to have a controlled process (not with setTimeout
) of knowing when the visible items are fully rendered.
Thanks.
const renderItem = ({ item }) => ( <Item name={item.name} isSelected={item. isSelected} /> ); Display the FlatList React Native component as before… return ( <View style={styles. container}> <FlatList data={countries} renderItem={renderItem} keyExtractor={(item) => item.id} /> </View> );
keyExtractor (item: object, index: number) => string; Used to extract a unique key for a given item at the specified index. Key is used for caching and as the react key to track item re-ordering. The default extractor checks item.key , then item.id , and then falls back to using the index, like React does.
I ended up using the componentDidMount
of the renderItem
component as an indicator that element is rendered.
In the below example ActivityIndicator
will be shown until the first 10 items are rendered (the number I set in the initialNumToRender
).
This approach is not ideal. You may need to tweak it for your case but the general idea is shown below.
Here is the list item:
class ListItem extends React.Component<{ onRendered: () => void }> {
componentDidMount(): void {
this.props.onRendered();
}
render() {
return (
<View>
<Text>Item</Text>
</View>
);
}
}
And here is the screen with FlatList
that uses above ListItem:
export class FlatListTestScreen extends React.Component<any, { creating: boolean }> {
constructor(props: any, context: any) {
super(props, context);
this.state = {
creating: true,
};
}
onRenderedItem = () => {
this.setState({
creating: false,
});
};
renderItem = (item: any) => {
return <ListItem onRendered={this.onRenderedItem} />;
};
dataArray = Array(20)
.fill('')
.map((_, i) => ({ key: `${i}`, text: `item #${i}` }));
render() {
const loader = this.state.creating ? <ActivityIndicator /> : <></>;
return (
<View>
{loader}
<FlatList
initialNumToRender={10}
data={ this.dataArray }
renderItem={ this.renderItem }
keyExtractor={ item => item.key }
/>
</View>
);
}
}
I also tried to use a map to collect the number of rendered items but on practice it seems that they all fire componentDidMount
at the same time so simpler approach may be better.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With