Lazy list loading

In this section, you'll implement a different kind of list, one that scrolls infinitely. Sometimes, users don't actually know what they're looking for, so filtering or sorting isn't going to help. Think about the Facebook news feed you see when you log into your account; it's the main feature of the application and rarely are you looking for something specific. You'll need to see what's going on by scrolling through the list.

To do this using a FlatList component, you need to be able to fetch more API data when the user scrolls to the end of the list. To get an idea of how this works, you need a lot of API data to work with. Generators are great at this! So let's modify the mock that you created in the previous example so that it just keeps responding with new data:

// Items...keep'em coming!
function* genItems() {
let cnt = 0;

while (true) {
yield `Item ${cnt++}`;
}
}

const items = genItems();

export const fetchItems = () =>
Promise.resolve({
json: () =>
Promise.resolve({
items: new Array(20).fill(null).map(() => items.next().value)
})
});

With this in place, you can now make an API request for new data every time the end of the list is reached. Well, eventually this will fail when you run out of memory, but I'm just trying to show you in general terms the approach you can take to implement infinite scrolling in React Native. Here's what the ListContainer component looks like:

import React, { Component } from 'react';

import * as api from './api';
import List from './List';

class ListContainer extends Component {
state = {
data: [],
asc: true,
filter: ''
};

fetchItems = () =>
api
.fetchItems()
.then(resp => resp.json())
.then(({ items }) =>
this.setState(state => ({
data: [...state.data, ...items.map((value, i) => ({
key: i.toString(),
value
}))]
})
);

// Fetches the first batch of items once the
// component is mounted.
componentDidMount() {
this.fetchItems();
}

render() {
return (
<List data={this.state.data} fetchItems={this.fetchItems} />
);
}
}

export default ListContainer;

Each time fetchItems() is called, the response is concatenated with the data array. This becomes the new list data source, instead of replacing it as you did in earlier examples. Now, let's take a look at the List component to see how to respond to the end of the list being reached:

import React from 'react';
import PropTypes from 'prop-types';
import { Text, FlatList } from 'react-native';

import styles from './styles';

// Renders a "<FlatList>" component, and
// calls "fetchItems()" and the user scrolls
// to the end of the list.
const List = ({ data, fetchItems }) => (
<FlatList
data={data}
renderItem={({ item }) => (
<Text style={styles.item}>{item.value}</Text>
)}
onEndReached={fetchItems}
/>
);

List.propTypes = {
data: PropTypes.array.isRequired,
fetchItems: PropTypes.func.isRequired
};

export default List;

If you run this example, you'll see that, as you approach the bottom of the screen while scrolling, the list just keeps growing.

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

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