javascriptreact-nativereact-native-flatlistseparatorflatlist

Add a separator every 3 item in flatlist - React Native


How can I add a separator for every 3 items in flatlist? I can just add a separator after every 1 item. I did not find a prop for that. Here are my codes:

import React from 'react';
import { SafeAreaView, View, FlatList, StyleSheet, Text} from 'react-native';

const DATA = [
    {
        id: 1,
        title: 'Item 1',
    },

    {
        id: 2,
        title: 'Item 2',
    },
    {
        id: 3,
        title: 'Item 3',
    },
    {
        id: 4,
        title: ' Item 4',
    },
    {
        id: 5,
        title: 'Item 5',
    },
    {
        id: 6,
        title: 'Item 6',
    },
    {
        id: 7,
        title: 'Item 7',
    },
];


const App = () => {

    const renderItem = ({ item }) => (
        <View style={styles.item}>
            <Text style={styles.title}>{item.title}</Text>
        </View>
    );

    const seperator = () => {
        return (
            <View style={styles.seperator} />
        )
    }

    return (
        <SafeAreaView style={styles.container}>
            <FlatList
                data={DATA}
                renderItem={renderItem}
                keyExtractor={(items) => items.id}
                ItemSeparatorComponent={seperator}
            />
        </SafeAreaView>
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    item: {
        backgroundColor: '#f9c2ff',
        padding: 10,
        marginVertical: 8,
        marginHorizontal: 16,
    },
    title: {
        fontSize: 32,
    },
    seperator: {
        width: 300,
        height: 10,
        backgroundColor: 'red'
    }
});

export default App;

My app looks likes:

enter image description here

But I want to make that:

enter image description here

How can I add a separator for every 3 items in flatlist? I can just add a separator after every 1 item. I did not find a prop for that.


Solution

  • In case your data items do not have an id or a property that can easily distinguish two items, consider using a counter to keep track of how many times your separator function was called.

    To do so, useRef hook can be used, as:

    useRef returns a mutable ref object whose .current property is initialized to the passed argument

    And since this hook is mutable, it's possible to count how many times the function is called, thus tracking how many items are skipped.

    import { useState, useRef } from 'react'; 
    
    const App = () => { 
        let [skipItems,] = useState(3); // change to the number of items to skip
        let count = useRef(0);
    
        const separator = (e) => {
              count.current += 1;
              return (
                (count.current % skipItems === 0) ? <View style={styles.separator}/> 
                                                  : null
             );
        }
    
        return (
                <SafeAreaView style={styles.container}>
                    <FlatList
                        data={DATA}
                        renderItem={renderItem}
                        ItemSeparatorComponent={(e) => separator(e)}
                    />
                </SafeAreaView>
        );
    }
    

    Notes:

    1. If you prefer, you can choose the useState hook instead;
    2. It is important to work with some key in keyExtractor property for FlatList, because it is used for caching and as the react key to track item re-ordering.