How to create a ListView in React Native with Section Headers

Let's create a ListView with section headers in React Native.

First, we need a suitable data to show with sections and rows. I copied this data from a pizza restaurant menu.

var menuData = {
menu : [
{
menuSectionId : 1,
menuSectionName : 'Classic Pizzas',
items : [
{
itemId : 1,
itemName : 'Margharita',
itemDescription : 'Cheese & tomato',
itemPrice : 3.95
},
{
itemId : 2,
itemName : 'Mediterranean',
itemDescription : 'Mushrooms, green peppers, red onion & garlic',
itemPrice : 4.95
},
{
itemId : 3,
itemName : 'Pepperoni Passion',
itemDescription : 'Heaps of pepperoni',
itemPrice : 4.95
},
{
itemId : 4,
itemName : 'Chicken Feast',
itemDescription : 'Chicken, mushrooms & sweetcorn',
itemPrice : 4.95
},
]
},
{
menuSectionId : 2,
menuSectionName : 'Favourite Pizzas',
items : [
{
itemId : 5,
itemName : 'Hot & Spicy',
itemDescription : 'Onions, spicy mince, jalapenos & mixed peppers',
itemPrice : 5.95
},
{
itemId : 6,
itemName : 'Tandoori Sizzler',
itemDescription : 'Tandoori chicken, onions, mushrooms, green peppers & jalapenos',
itemPrice : 6.95
},
{
itemId : 7,
itemName : 'Vegetarian Supreme',
itemDescription : 'Onions, green peppers, sweetcorn, mushrooms & tomatoes',
itemPrice : 5.95
},
{
itemId : 8,
itemName : 'Meatilicious',
itemDescription : 'Spicy mince, pepperoni & chicken tikka',
itemPrice : 6.95
},
{
itemId : 9,
itemName : 'Mexican',
itemDescription : 'Spicy mince, pepperoni & red onions',
itemPrice : 5.95
},
{
itemId : 10,
itemName : 'Prestige',
itemDescription : 'Pepperoni, chicken tikka, spicy mince, red onions, green peppers & mushrooms',
itemPrice : 6.95
},
]
},
{
menuSectionId : 3,
menuSectionName : 'Sides',
items : [
{
itemId : 11,
itemName : 'Potato Wedges',
itemDescription : null,
itemPrice : 1.55
},
{
itemId : 12,
itemName : 'Fries',
itemDescription : null,
itemPrice : 1.55
},
{
itemId : 13,
itemName : 'Vegetable Pakora',
itemDescription : null,
itemPrice : 1.95
},
{
itemId : 14,
itemName : 'Chicken Pakora',
itemDescription : null,
itemPrice : 2.95
},
{
itemId : 15,
itemName : 'Mushroom Pakora',
itemDescription : null,
itemPrice : 1.95
},
{
itemId : 16,
itemName : 'Chicken Wings (6 pcs)',
itemDescription : null,
itemPrice : 3.95
},
{
itemId : 17,
itemName : 'Plain Nan',
itemDescription : null,
itemPrice : 1.95
},
{
itemId : 18,
itemName : 'Garlic Nan',
itemDescription : null,
itemPrice : 2.25
},
]
},
]
};

To show this data as list view we need to restructure this data as list view wants. List view wants 3 things.

  1. data blob, which is an object
  2. sections ids, which is an array of strings
  3. row ids, which is an array of array of strings [[‘s1’, ‘s2’], [‘s3’], [‘s4’]]

You can look the code piece’s comments for more explanation.

_getStructuredData(data){/* sample of data will return
dataBlob must be an object
sectionIds must be an array of strings
rowIds must be an array of array of strings
var dataBlob = {
's1' : {
'sample' : 'sample1',
'blabla' : 'blablabla1',
's1r1' : { a : 1, b : 1 },
's1r2' : { a : 2, b : 2 },
},
's2' : {
'sample' : 'sample2',
'blabla' : 'blablabla2',
's2r1' : { a : 3, b : 3 },
's2r2' : { a : 4, b : 4 },
}
};
var sectionIds = ['s1','s2'];
var rowIds = [ ['s1r1','s1r2'], ['s2r1', 's2r2'] ];
*/
var dataBlob = {};
var sectionIds = [];
var rowIds = [];
data.menu.forEach(function(menuSection){
var section = menuSection;
var menuSectionId = 's' + section.menuSectionId; // section id will be a string
var rIds = [];
menuSection.items.forEach(function(item){
var itemId = menuSectionId + 'i' + item.itemId;
section[itemId] = item;
rIds.push(itemId);
});
dataBlob[menuSectionId] = section;
sectionIds.push(menuSectionId);
rowIds.push(rIds);
});
console.log(' dataBlob :', dataBlob );
console.log(' sectionIds :', sectionIds );
console.log(' rowIds :', rowIds );
return {
dataBlob : dataBlob,
sectionIds : sectionIds,
rowIds : rowIds
};
}

Section headers sticks to the top of list view as default on ios. But android doesn’t have this feature now as react native 0.31.

You can find full code at https://rnplay.org/apps/Byto6A . also you can try it from that link.

Here’s a picture of how it looks: