How to Make Header of FlatList Sticky in React Native

Last Updated on December 14, 2020.

If your react native app shows some good amount of data to the user then most probably, you would be using FlatList component. FlatList is an enhanced component to render data in lists. In this blog post, I am writing about how to make the header component of FlatList sticky.

First of all, how to add a header to your FlatList? Adding header component is easy by making use of FlatList prop ListHeaderComponent. For example, look at the following snippet.

  header= () => {
    return(
    <View style={styles.headerStyle}>
      <Text style={styles.titleStyle}>POSTS</Text>
    </View>);
  }

    return (
      <View style={styles.container}>
       <FlatList
        data={this.state.data}
        ListHeaderComponent={this.header}
        renderItem={({item}) => <Text>{item.title}</Text>}
        />
      </View>
    );
 

I hope you get it. ListHeaderComponent accepts a React component class or rendered element or a render function. But the problem with this header component is- it’s not sticky. The header would disappear when we begin to scroll down through the FlatList.

So, how to make the header component of the FlatList sticky in react native?

By using stickyHeaderIndices prop. It is the prop of ScrollView component which can be used by the FlatList too. The prop stickyHeaderIndices accepts an array of indices of the children which needed to be sticky. In the case of FlatList, header component has a child index of 0. Hence using stickyHeaderIndices={[0]} make the header of your FlatList sticky.

Following is a complete react-native example which shows the sticky header in FlatList.

Class based component

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

class MyClass extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: '',
    };
  }

  componentDidMount() {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then((response) => response.json())
      .then((json) =>
        this.setState({
          data: json,
        }),
      );
  }

  header = () => {
    return (
      <View style={styles.headerStyle}>
        <Text style={styles.titleStyle}>POSTS</Text>
      </View>
    );
  };

  render() {
    return (
      <View style={styles.container}>
        <FlatList
          keyExtractor={(item) => item.id.toString()}
          data={this.state.data}
          ListHeaderComponent={this.header}
          stickyHeaderIndices={[0]}
          renderItem={({item}) => <Text>{item.title}</Text>}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'white',
  },
  buttonView: {
    flexDirection: 'row',
  },
  headerStyle: {
    flex: 1,
    height: 40,
    width: '100%',
    backgroundColor: 'blue',
    justifyContent: 'center',
    alignItems: 'center',
  },
  titleStyle: {
    color: 'white',
  },
});

export default MyClass;

Function based component

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

const MyClass = () => {
  const [data, setData] = useState('');
  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then((response) => response.json())
      .then((json) => setData(json));
  }, []);

  const header = () => {
    return (
      <View style={styles.headerStyle}>
        <Text style={styles.titleStyle}>POSTS</Text>
      </View>
    );
  };

  return (
    <View style={styles.container}>
      <FlatList
        keyExtractor={(item) => item.id.toString()}
        data={data}
        ListHeaderComponent={header}
        stickyHeaderIndices={[0]}
        renderItem={({item}) => <Text>{item.title}</Text>}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'white',
  },
  buttonView: {
    flexDirection: 'row',
  },
  headerStyle: {
    flex: 1,
    height: 40,
    width: '100%',
    backgroundColor: 'blue',
    justifyContent: 'center',
    alignItems: 'center',
  },
  titleStyle: {
    color: 'white',
  },
});

export default MyClass;

The output of the react-native example is as given below:

sticky flatlist header

2 thoughts on “How to Make Header of FlatList Sticky in React Native”

  1. Pingback: How to Add Footer to FlatList in React Native - REACT NATIVE FOR YOU

Leave a Reply

%d bloggers like this: