James111
James111

Reputation: 15903

How can we prepend rows to a react native list-view?

I've looked almost everywhere to find a solution to this!

Is there a way of prepending rows to a listview without re-rendering every single row? I find it bizarre that facebook haven't included a way to do this in there documentation! I feel as though there could be a memory efficient way of doing this as you can do it with the native scripts (java, swift).

There are a lot of discussions that try to solve it, such as this one:

https://github.com/facebook/react-native/issues/1682

But as of yet I haven't found an efficient way of doing this.

Upvotes: 2

Views: 1917

Answers (1)

Mihir
Mihir

Reputation: 3902

There is no direct method to prepend rows to your ListView. There is not much documentation on ListView.DataSource out there. So here it goes-

If you want to add/append/prepend/update/delete rows from a ListView, all you have to do is just update the dataSource and call cloneWithRows() in setState.

For eg. I want to fetch data from a URL. Each time I hit "Load more", I append new rows to my data source.

getInitialState: function(){
    return {
        rawData: [],
        dataSource: new ListView.DataSource({
          rowHasChanged: (row1, row2) => row1 !== row2
        }),
        loaded: false,
        page: 1,
    }
},

At the very first time, I call this function in ComponentDidMount() which populates my ListView with initial data and "page"=1 in the state.

  reloadData: function(){
    this.setState({ loaded: false, rawData: [], page: 1 });

    API.getUpcomingMovies(this.state.page)
      .then((data) => {
          this.setState({
            rawData: this.state.rawData.concat(data),
            dataSource: this.state.dataSource.cloneWithRows(this.state.rawData.concat(data)),
            loaded: true,
          });
      });
  },

And every time I tap on "load more" to get JSON from the API, I call the following function. Where "page" is incremented every time I hit "load more".

fetchData: function(){

    this.setState({ loaded: false, page: this.state.page+1 });

    API.getUpcomingMovies(this.state.page)
        .then((data) => {
            this.setState({
              rawData: this.state.rawData.concat(data),
              dataSource: this.state.dataSource.cloneWithRows(this.state.rawData.concat(data)),
              loaded: true,
            });
        });
  },

As you can see, I am concatenating my rawData[] (which is a simple array holding JSON objects). If you want to prepend new data to your rawData, you can do something like this-

this.setState({
    rawData: data.concat(this.state.rawData)
)}

Upvotes: 7

Related Questions