React Native ListView with Section Headers


June 16, 2015
ReactNativelogo

Introduction

React Native is an exciting framework that enables the developer to easily build native apps using a common web development stack. In a nutshell, you will be able to use the same codebase to build a native iOS and Android* application. You can read more about React Native in our introduction to React Native post. Once you dive into coding a React Native app, Jay Garcia’s article on building Custom Components is an excellent resource.

ListView

Many applications available today display data in a list in some shape or form. It can either be a Contact List, Settings, Application Navigation and many more. One of the core components that React Native provides is a ListView. Simple ListViews work on a concept of a data array added to a ListView.DataSource instance and a renderRow function implementation that instructs the ListView how to render the row. The ListView component also supports rendering static headers/footers, as well as callbacks for reaching end of available data and getting the set of rows when the viewport changes.

ListView with Sections

Sections are used to provide logical grouping and separation to a list’s contents. Generally they are used when the data is hierarchical, such as organization user lists or schedules. In our example we’re going to display a list of organizations and the users belonging to each organization.

image001

Sample Organization List app using a ListView with Section Headers

To achieve getting the data correctly into the ListView we need to set up the 3 data structures required by the ListView DataSource: an array of Section IDs, an array of Row IDs and most importantly an object that holds the data that we’ll refer to as dataBlob.

dataBlob

The dataBlob is a data structure (generally an object) that holds all the data powering the ListView. It contains the Section Header data as well as the individual Row Data for each row. We will implement lookup functions (getSectionData and getRowData) that access the dataBlob and return the necessary data for each section and row.

image002

Sections

To display sections we need an array of Section IDs to contain unique identifiers for each section. To lookup the value for the section header we need to implement a getSectionData method.

image003

Rows

In order to display rows , we need to follow a similar pattern as displaying the section headers by having an array of Row IDs. The structure of the Row IDs array is slightly different as it contains an array of Row IDs for each section index.

image004

Implementation

On the code side of things there are a few things we need to do different than implementing a section-free ListView.

  1. First and foremost we need to initialize our DataSource and implement the necessary getSectionData and getRowData methods.

  2. Then we need to populate our 3 data structures mentioned earlier. In our sample app we use a mock JSON in the following structure and content:

  3. Here’s how we process the JSON data to build the Section IDs array, Row IDs array, and dataBlob object.

Working Example

You can find the source for the entire application in this GitHub Repo.

Wrap Up

In this post we took a look at the React Native ListView component and how to render section headers. In the process we took a dive into how the data source should be configured for the ListView with sections. Going forward we’re going to begin diving into React Native even further, exploring its ES6 capabilities, animations, and more of its expansive feature set.


Bershadskiy_Stan square
Stan Bershadskiy is an architect at Modus Create and specializes in all things JavaScript with vast knowledge in Sencha frameworks. Recently, he has directed his focus towards React Native and has co-authored The React Native Cookbook, which was released in December 2016. Stan is located in New York City and can be found co-organizing NYC.JS Meetups and presenting at conferences around the country.

  • dbieber

    How does react know what rowIds to call getRowData with?

    • Stan Bershadskiy

      RN’s ListView works on a page-based structure. Based on the active page it will call getRowData for each one of the rows it renders. I haven’t looked in the source code to see if it has any trailing/leading buffers to be honest. However, you can see it in action if you set up a console logger on that getRowData call, you will see it call the function as you’re scrolling past the pages.

  • Shrey Mahajan

    I am making an app in which data is read from database and displayed in list .Each list item has a ‘+’ and ‘-‘ button which increses and decreases the counter value .When i press button my value is not change.How can i fix that

    • Stan Bershadskiy

      Are you updating the state properly? If you have a code snippet of that class I may be able to help you out better.

      • kim liu

        Hi, I have the same problem with Shrey. Could you help with me?

  • Derese Getachew

    @stanbershadskiy:disqus thank you for the great post and i have been referring to this post every time i had to work with listviews that have sectionHeaders.

    While working with cloneWithRowsAndSections though i have run into a problem. My problem is how to edit an Item in a row where it also has a sectionHeader. the picture below explains well what i am trying to do. What i am trying to do is a Contacts List where the they are grouped by the Alphabets A-Z. So the concept is when you click on a specific user it will drill down or navigate to another page; where you can edit lets say for example the name of the user; so I go and edit the name from xxxx lets say xAAAA ; when i go back it should navigate back to the list view and the row item with name xxxx should now be updated with xAAAA. Can you help me understand how row editing works when we are using cloneWithRowsAndSections. my problem is not actually with Adding or deleting items to the rows the change is not being propagated when i make edits; even the rowHasChanged Returns true for a change but its not updating . if you have a general guideline that can help me i would appreciate it so much.

  • Bruce

    Thanks,good tutorial !

  • Sam

    Thanks for the article and example code Stan. Using your example, how would one go about filtering for gender?

    • Stan Bershadskiy

      You would have to rebuild the dataBlob, sectionIDs, and rowIDs as you do in Step 3 with the filter for the selected gender. Then when you call this.setState() with your new DataSource, it will update the ListView and instruct it to re-render with the new data.

  • Manjeet Singh

    Thanks for the tutorial, I want to render header without no data , and then will add rows to header on scroll how should I proceed

  • rolando barbella

    Would be great to see the actual code working with everything in place :)


What We Do

We’ll work closely with your team to instill Lean practices for ideation, strategy, design and delivery — practices that are adaptable to every part of your business.

See what Modus can do for you.

LET'S GET STARTED

We're Hiring!

Join our awesome team of dedicated engineers.

Loading...

APPLY NOW