Day 5: Working with Lists and ScrollViews


In this tutorial, you’ll learn how to display and manage dynamic lists in React Native. Lists are a crucial part of any app, allowing you to show data sets efficiently. We will also cover how to implement scrolling behavior using ScrollView and FlatList. By the end of this tutorial, you’ll be able to render long lists of data and scroll through them.


What You Will Learn Today:

  1. Using ScrollView to handle scrollable content
  2. Displaying a list of items using FlatList
  3. Rendering complex lists with custom components
  4. Optimizing list rendering with FlatList for large datasets

Step 1: Working with Scrollable Content Using ScrollView

The ScrollView component allows you to create scrollable views when content exceeds the screen size. Let’s start by rendering long content inside a ScrollView.

Modify HomeScreen.js to wrap the current content in a ScrollView:

import React, { useState } from 'react';
import { View, Text, TextInput, Button, ScrollView, StyleSheet } from 'react-native';

export default function HomeScreen({ navigation }) {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [errorMessage, setErrorMessage] = useState('');

  const handlePress = () => {
    if (!name || !email) {
      setErrorMessage('Please enter both your name and email.');
    } else {
      setErrorMessage('');
      navigation.navigate('Details', { name, email });
    }
  };

  return (
    <ScrollView contentContainerStyle={styles.container}>
      <Text style={styles.title}>Welcome to the Home Screen</Text>

      {errorMessage ? <Text style={styles.error}>{errorMessage}</Text> : null}

      <TextInput
        style={styles.input}
        placeholder="Enter your name"
        value={name}
        onChangeText={setName}
      />

      <TextInput
        style={styles.input}
        placeholder="Enter your email"
        value={email}
        onChangeText={setEmail}
        keyboardType="email-address"
      />

      <Button title="Go to Details" onPress={handlePress} />

      {/* Long content here */}
      <Text style={styles.longText}>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin nec massa nec ligula cursus sagittis.
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ultricies malesuada eros a vehicula.
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce vehicula, tortor in egestas aliquet, justo est ultricies risus.
        {/* Repeat this text several times */}
      </Text>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    flexGrow: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
    backgroundColor: '#f5f5f5',
  },
  title: {
    fontSize: 24,
    marginBottom: 20,
  },
  input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    width: '80%',
    paddingHorizontal: 10,
    marginBottom: 20,
  },
  error: {
    color: 'red',
    marginBottom: 10,
  },
  longText: {
    marginTop: 20,
    fontSize: 16,
    textAlign: 'justify',
  },
});

Explanation:

  • ScrollView: We wrapped all the content inside a ScrollView to make the view scrollable. The contentContainerStyle is used to ensure the inner views are styled correctly.
  • You can add long text (like in the example) or multiple components inside the ScrollView to make the content scrollable.
See also  Day 7: Integrating Push Notifications with Firebase Cloud Messaging (FCM)

Step 2: Introducing Lists Using FlatList

React Native provides a powerful and efficient way to render lists using the FlatList component. Unlike ScrollView, FlatList is optimized for rendering large data sets by rendering only the visible items, improving performance.

Let’s start by displaying a list of items on the HomeScreen. Modify the HomeScreen.js to include a FlatList:

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

export default function HomeScreen({ navigation }) {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [errorMessage, setErrorMessage] = useState('');

  const data = [
    { id: '1', name: 'Item 1' },
    { id: '2', name: 'Item 2' },
    { id: '3', name: 'Item 3' },
    { id: '4', name: 'Item 4' },
    { id: '5', name: 'Item 5' },
  ];

  const handlePress = () => {
    if (!name || !email) {
      setErrorMessage('Please enter both your name and email.');
    } else {
      setErrorMessage('');
      navigation.navigate('Details', { name, email });
    }
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Welcome to the Home Screen</Text>

      {errorMessage ? <Text style={styles.error}>{errorMessage}</Text> : null}

      <TextInput
        style={styles.input}
        placeholder="Enter your name"
        value={name}
        onChangeText={setName}
      />

      <TextInput
        style={styles.input}
        placeholder="Enter your email"
        value={email}
        onChangeText={setEmail}
        keyboardType="email-address"
      />

      <Button title="Go to Details" onPress={handlePress} />

      <FlatList
        data={data}
        keyExtractor={(item) => item.id}
        renderItem={({ item }) => (
          <View style={styles.listItem}>
            <Text style={styles.itemText}>{item.name}</Text>
          </View>
        )}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
    backgroundColor: '#f5f5f5',
  },
  title: {
    fontSize: 24,
    marginBottom: 20,
  },
  input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    width: '80%',
    paddingHorizontal: 10,
    marginBottom: 20,
  },
  error: {
    color: 'red',
    marginBottom: 10,
  },
  listItem: {
    padding: 10,
    backgroundColor: '#f9c2ff',
    marginVertical: 8,
    borderRadius: 10,
    width: '100%',
  },
  itemText: {
    fontSize: 16,
    textAlign: 'center',
  },
});

Explanation:

  • FlatList: Renders a list of items. We pass the data prop to supply the list items and the renderItem prop to specify how each item should be displayed.
  • keyExtractor: Provides a unique key for each item in the list, which helps React Native optimize rendering.
  • The list is styled with custom colors and rounded borders for each item.
See also  Real-Time Applications with Laravel and WebSockets: A Comprehensive Guide

Step 3: Adding More Complex List Items

Let’s make the list items more complex by adding an additional field and customizing the display. Modify the data array to include more details for each item:

const data = [
  { id: '1', name: 'Item 1', description: 'This is the first item' },
  { id: '2', name: 'Item 2', description: 'This is the second item' },
  { id: '3', name: 'Item 3', description: 'This is the third item' },
  { id: '4', name: 'Item 4', description: 'This is the fourth item' },
  { id: '5', name: 'Item 5', description: 'This is the fifth item' },
];

Update the renderItem function to display both the name and description:

<FlatList
  data={data}
  keyExtractor={(item) => item.id}
  renderItem={({ item }) => (
    <View style={styles.listItem}>
      <Text style={styles.itemText}>{item.name}</Text>
      <Text>{item.description}</Text>
    </View>
  )}
/>

Now, each list item will display both the name and description fields.


Step 4: Optimizing Lists for Large Datasets

When dealing with larger datasets, it’s essential to make sure that the app remains performant. The FlatList component provides features such as lazy loading and item recycling, which ensures that only the visible items are rendered. Here are some tips for optimizing lists:

  1. Use getItemLayout: If you know the height of your list items, using getItemLayout helps React Native optimize rendering by skipping unnecessary layout calculations.
  2. Enable Pagination: For very large datasets, consider using pagination (loading data in chunks).

You can enable pagination in FlatList by using the onEndReached prop:

<FlatList
  data={data}
  keyExtractor={(item) => item.id}
  renderItem={({ item }) => (
    <View style={styles.listItem}>
      <Text style={styles.itemText}>{item.name}</Text>
      <Text>{item.description}</Text>
    </View>
  )}
  onEndReached={() => {
    // Load more data when the user reaches the end of the list
    console.log('End of list reached!');
  }}
  onEndReachedThreshold={0.5}
/>

Step 5: Testing the App

Run your app with npm start and test the new scrollable content and list features on your mobile device using the Expo Go app.

See also  Day 4: Handling Side Effects with Redux-Saga

You should now see:

  • A scrollable form with long content.
  • A dynamic list of items rendered with FlatList.
  • Additional item details (name and description) displayed for each list item.

Step 6: Recap and Summary

Today, you learned how to handle long content and lists in React Native. Here’s a quick summary of what you’ve done:

  • Implemented scrollable views using ScrollView.
  • Rendered dynamic lists of items using FlatList.
  • Customized list items and displayed complex data.
  • Optimized list rendering for better performance.

With these skills, you can now build rich, dynamic views that can handle long content and data sets!


Next Up: Day 6 – Fetching Data from APIs

In Day 6, we’ll focus on integrating external data by fetching content from APIs. You’ll learn how to fetch data from a remote source and dynamically render it in your app using the skills you’ve learned today.

Stay tuned for more exciting features tomorrow!


Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.