Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reload ListView not Working React Native

Re-phrasing my Question... (Tested with separate class)

I am trying to reload listview with random array on a button press. But it's not working! Trying to do refresh datasource this with following LOC:

_buttonPressed() {
        this.setState({
            dataSource: this.state.dataSource.cloneWithRows(this._randomArray()),
        });
    }

_randomArray() {

    var jsonRes;

    switch(this.getRandomInt()) // number returned is valid. I checked
    {
        case 1:
        {
            jsonRes = '[' +
            '{ "firstName":"Michel" , "lastName":"John" ,"age":18},' +
            '{ "firstName":"Richard" , "lastName":"Joe","age":20 },' +
            '{ "firstName":"James" , "lastName":"Henry","age":15 },' +
            '{ "firstName":"e" , "lastName":"u","age":15 }]';
            break;
        }
        case 2:
        {
            jsonRes = '[' +
            '{ "firstName":"bacde" , "lastName":"John" ,"age":18},' +
            '{ "firstName":"bacde" , "lastName":"Joe","age":20 },' +
            '{ "firstName":"bacde" , "lastName":"Henry","age":15 },' +
            '{ "firstName":"ebacde" , "lastName":"u","age":15 }]';
            break;
        }
        case 3:
        {
            jsonRes = '[' +
            '{ "firstName":"mmmmm" , "lastName":"John" ,"age":18},' +
            '{ "firstName":"mmmmm" , "lastName":"Joe","age":20 },' +
            '{ "firstName":"mmmmm" , "lastName":"Henry","age":15 },' +
            '{ "firstName":"etttttt" , "lastName":"u","age":15 }]';
            break;
        }
        default:
        {
            jsonRes = '[' +
            '{ "firstName":"dddd" , "lastName":"John" ,"age":18},' +
            '{ "firstName":"dddd" , "lastName":"Joe","age":20 },' +
            '{ "firstName":"dddd" , "lastName":"Henry","age":15 },' +
            '{ "firstName":"ehhgh" , "lastName":"u","age":15 }]';
            break;
        }
    }

    var myObject = eval('(' + jsonRes + ')');
    return myObject;

}

I have already seen example listview projects of React Native. They are using dataSource.cloneWithRows for this purpose. Don't know what small thing I am missing. Please help me to sort out this issue... Thanks!

like image 294
NightFury Avatar asked May 06 '15 07:05

NightFury


People also ask

How to swipe down to refresh list view in React Native?

Here is an example of React Native Swipe Down to Refresh List View Using Refresh Control. It was first introduced in Android Material Design and became very popular. Almost all Apps are using Swipe down to refresh. In React Native you can use this feature using RefreshControl provided by React Native.

How to make a react native app with React Native CLI?

We are going to use react-native init to make our React Native App. Assuming that you have node installed, you can use npm to install the react-native-cli command line utility. Open the terminal and go to the workspace and run If you want to start a new project with a specific React Native version, you can use the --version argument:

How to create a listview component from an array?

The minimal API is to create a ListView.DataSource, populate it with a flat array of data blobs, and instantiate a ListView component with that data source and a renderRow callback which takes a blob from the data array and returns a renderable component.

What is refreshcontrol in React Native?

It was first introduced in Android Material Design and became very popular. Almost all Apps are using Swipe down to refresh. In React Native you can use this feature using RefreshControl provided by React Native.


1 Answers

I have been able to successfully debug the issue. I just opened the source code for ListViewDataSource.js and traced the datablob variable value passed along the different functions.

A method _calculateDirtyArrays identifies which rows have been changed and need to be updated. For this, one of the three conditions must match for a row.

 ........
    // dirty if the section is new, row is new or _rowHasChanged is true
    dirty =
      !prevSectionsHash[sectionID] ||
      !prevRowsHash[sectionID][rowID] ||
      this._rowHasChanged(
        this._getRowData(prevDataBlob, sectionID, rowID),
        this._getRowData(this._dataBlob, sectionID, rowID)
      );
    this._dirtyRows[sIndex].push(!!dirty);
 ........

_rowHasChangedis the one passed to List Datasource constructor.

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

This was wrong in my case, since row should be changed when corresponding data changes. I changed above condition per my requirement.

var dataSource = new ListView.DataSource(
        {
            rowHasChanged: function(r1, r2) : bool {
                return (
                (r1["firstName"] !== r2["firstName"]) ||
                (r1["lastName"] !== r2["lastName"]) ||
                (r1["age"] !== r2["age"])
                );
            }
        });

and voila! It works perfect now. Hopefully it helps someone in future!

like image 87
NightFury Avatar answered Oct 22 '22 22:10

NightFury