Spierki
Spierki

Reputation: 241

ReactNative listview initial state

I have started developping a react native application and I have a problem with the initialization of my listview.

I'm using the react-native-db-models plugin to store and retrieve my data

The problem is that I want to get my data in the getInitialState function of my react listview and I need to call a callback function..

This is the code of my class for retrieving my data from the db :

'use strict';

var React = require('react-native');

var DB = require('./Database');

var DBEvents = require('react-native-db-models').DBEvents;

class BarcodeDAO {
  get_all_barcodes(success) {
    DB.barcodes.get_all(success);
  }
}

module.exports = BarcodeDAO;

And this is my code for the listview :

'use strict';

var React = require('react-native');

var {
  AppRegistry,
  Text,
  ListView,
  View,
} = React;

var BarcodeDAO = require('./BarcodeDAO');


var BarcodeList = React.createClass({
  statics: {
    title: '<ListView> - Simple',
    description: 'Performant, scrollable list of data.'
  },

  getInitialState: function() {
    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

    var barcodeDAO = new BarcodeDAO();

    barcodeDAO.get_all_barcodes(function(result) {
       var data = [];
       for(var i = 1; i <= result.totalrows; i++) {
         console.log(result.rows[i].barcode.value);
         data[i-1] = result.rows[i].barcode.value;
       }
       //THIS IS WHERE I DON'T KNOW HOW TO PASS THE VALUE THE THE return of the getInitialState function..
       //self.state.dataSource.cloneWithRows(data);
       //self.getDataSource(self,data);
    });

    return {
      dataSource: ds.cloneWithRows({??????})
    };
  },

  },

  getDataSource: function(self, barcodes: Array<any>): ListView.DataSource {
    console.log("update");
    return self.state.dataSource.cloneWithRows(barcodes);
  },

  render: function() {
    return (
      <ListView
        dataSource={this.state.dataSource}
        renderRow={(rowData) => <Text>{rowData}</Text>}
      />
    );
  },
});

module.exports = BarcodeList;

I'm new to react- and javascript so maybe it's obvious but I don't know how to make it..

Thanks in advance

Upvotes: 0

Views: 846

Answers (1)

Eyal Eizenberg
Eyal Eizenberg

Reputation: 4033

Because you need to fetch your data asynchronously, you should set the initial data like this:

getInitialState() {
  dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
}

in componentDidMount you should run the function that gets your data and once you have them you should do something like

this.setState({dataSource: state.dataSource.cloneWithRows(arrayOfBarcodes)})

Your list will automatically re-render with the correct data.

You can (and probably should) show a spinner while fetching the data. So just add to the initial state something like loaded: false and then when you got the data from the DB set the loaded to true as well:

this.setState({
  dataSource: state.dataSource.cloneWithRows(arrayOfBarcodes),
  loaded: true
})

and then in your render method do something like

render() {
  if (this.state.loaded) {
     this.renderTheListView()
  }
  else {
     this.renderLoadingIndicator()
  }
}

Upvotes: 4

Related Questions