React Native Sticky Date like whatsapp using Inverted SectionList

Mudaser Ali
3 min readMay 10, 2020

If you are currently developing a chat application and you have a requirement to stick a date while scrolling messages to let user know current date of messages user is viewing right now. This post is for you!

Find Demo

Inverted SectionList

If you create a SectionList with inverted false header stick properly while you scroll up and down

But when you use set inverted={true} SectionList its behaviour change you have to implement “renderSectionFooter” instead of “renderSectionHeader”

For example lets create a small app using following code

import React, { Component } from 'react';import { SafeAreaView, StyleSheet, View, Text, SectionList } from 'react-native';const DATA = [{title: '4th April, 2020',data: [  'Message No. 0',
................
'Message No. 19', ],},{title: '3rd April, 2020',data: [ 'Message No. 0',
................
'Message No. 19', ],},{title: '2nd April, 2020',data: [ 'Message No. 0',
................
'Message No. 19', ],},{title: '1st April, 2020',data: [ 'Message No. 0',
................
'Message No. 19', ],},];const Item = ({ title }) => ( <View style={styles.item}> <Text style={styles.title}>{title}</Text> </View>);class App extends Component {render() { return ( <> <SafeAreaView style={styles.container}> {this.renderStickyDate()} <SectionList sections={DATA} inverted={true} keyExtractor={(item, index) => item + index} renderItem={({ item }) => <Item title={item} />} renderSectionFooter={({ section: { title } }) => ( <View style={styles.stickyDate}> <Text style={styles.stickyDateText}>{title}</Text> </View> )} /> </SafeAreaView> </> ); }}

add simple style

const styles = StyleSheet.create({container: { flex: 1, marginHorizontal: 16,},item: { backgroundColor: '#f9c2ff', padding: 20, marginVertical: 8,},header: { fontSize: 24, backgroundColor: '#fff', alignSelf: 'center',},title: { fontSize: 24,},stickyDate: { alignSelf: 'center', textAlign: 'center', justifyContent: 'center', backgroundColor: '#f9c2ff', borderRadius: 10, marginBottom: 10,},stickyDateText: { color: '#000', padding: 5,},});

Result will be like this

Inverted SectionList
Inverted SectionList

You can see header is not stick; so if we need to implement sticky date like other chat apps we have to write some custom code

Luckily react-native’s SectionList provide us a property named onViewableItemsChanged. Read more

Now make following changes into your code

Add state currentDate

state = { currentDate: null,};

add a method to update currentDate value in state

updateStickyDate = ({ viewableItems, changed }) => { if (viewableItems && viewableItems.length) {  const lastItem = viewableItems.pop();  if (lastItem && lastItem.section) {    this.setState({     currentDate: lastItem.section.title,    });   } }};

add render date method to show date of viewable items/messages

renderStickyDate = () => {  const { currentDate } = this.state;  return currentDate ? (   <View style={styles.stickyDate}>     <Text style={styles.stickyDateText}>{currentDate}</Text>   </View>  ) : null;};

add onViewableItemsChanged prop in SectionList

<SectionList  .....
onViewableItemsChanged={this.updateStickyDate}
/>

Final Code will be like this

Github: https://github.com/smali-kazmi/rn-sticky-date-demo

Thanks for reading this long post;

--

--

Mudaser Ali

{ name: Mudaser Ali aka SMAK, skills: NoBody is pErfect i M nObOdy, passion: {love: [programming, photography]} }