Chapter 16. Rendering Item Lists

In this chapter, you'll learn how to work with item lists. Working with lists is a common development activity when building applications for the Web. It's also relatively straightforward to build lists using the <ul> and <li> elements. Trying to do something similar on native mobile platforms is much more involved.

Thankfully, React Native provides a simple item list interface that hides all of the complexity. We'll kick things off by getting a feel for how item lists work by walking through an example. Then, we'll introduce some controls that change the data displayed in lists. Lastly, you'll see a couple of examples that fetch items from the network.

Rendering data collections

Let's start with a basic example. The React Native component you'll use to render lists is ListView, which works the same way on iOS and Android. List views take a data source property, which must be a ListView.DataSource instance. Don't worry; it's really just a wrapper around an array in most cases. The reason that the ListView component expects this type of data source is so that it can perform efficient rendering. Lists can be long and updating them frequently can cause performance issues.

So, let's implement a basic list now, shall we? Here's the code to render a basic 100-item list:

import React from 'react'; 
import { 
  AppRegistry, 
  Text, 
  View, 
  ListView, 
} from 'react-native'; 
 
import styles from './styles'; 
 
// You always need a comparator function that's 
// used to determine whether or not a row has 
// changed. Even in simple cases like this, where 
// strict inequality is used. 
const rowHasChanged = (r1, r2) => r1 !== r2; 
 
const source = new ListView 
  // A data source for the list. It's eventually passed 
  // to the "<ListView>" component, and it requires a 
  // "rowHasChanged()" comparator. 
  .DataSource({ rowHasChanged }) 
 
  // Returns a clone of the data source with new data. 
  // The comparator function is used by the "<ListView>" 
  // component to determine what has changed. 
  .cloneWithRows( 
    new Array(100) 
      .fill(null) 
      .map((v, i) => `Item ${i}`) 
  ); 
 
const RenderingDataCollections = () => ( 
  <View style={styles.container}> 
    { /* Renders the list by providing a "dataSource" 
         property and a "renderRow" function which 
         renders each item in the list. */ } 
    <ListView 
      dataSource={source} 
      renderRow={ 
        i => (<Text style={styles.item}>{i}</Text>) 
      } 
    /> 
  </View> 
); 
 
AppRegistry.registerComponent( 
  'RenderingDataCollections', 
  () => RenderingDataCollections 
); 

Let's walk through what's going on here, starting with the source constant. As you can see, this is created using the ListView.DataSource() constructor. Here, we're giving it a rowHasChanged() function. Data sources need to be told how to look for changes, even if it's a simple equality check. Then, we pass the actual data into the cloneWithRows() method. This actually results in a new instance of the data source, and is actually a confusing name because none of the data is actually cloned. All you're cloning are the options you give the data source, such as the rowHasChanged() function for example. DataSource instances are immutable, and we'll see how to actually update them in the following examples.

Next, we render the <ListView> component itself. It's within a <View> container because list views need a height in order to make scrolling work correctly. The source and the renderRow properties are passed to the <ListView>, which ultimately determines the rendered content.

At first glance, it would seem that the ListView component doesn't do too much for us. We have to figure out how the items look? Well, yes, the ListView is supposed to be generic. It's supposed to excel at handling updates, and embeds scrolling capabilities into lists for us. Here are the styles that were used to render the list:

import { StyleSheet } from 'react-native'; 
 
export default StyleSheet.create({ 
  container: { 
    // Flexing from top to bottom gives the 
    // container a height, which is necessary 
    // to enable scrollable content. 
    flex: 1, 
    flexDirection: 'column', 
    paddingTop: 20, 
  }, 
 
  item: { 
    margin: 5, 
    padding: 5, 
    color: 'slategrey', 
    backgroundColor: 'ghostwhite', 
    textAlign: 'center', 
  }, 
}); 

Here, we're giving a basic style to each item in our list. Otherwise, each item would be text-only and would be difficult to differentiate between other list items. The container style gives the list a height by setting the flex direction to column. Without a height, you won't be able to scroll properly.

Let's see what this thing looks like now, shall we?

Rendering data collections

If you're running this example in a simulator, you can click and hold down the mouse button anywhere on the screen, like a finger, then scroll up or down through the items.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset