Randy Song
Randy Song

Reputation: 583

What are the exact inputs to rowHasChanged in ListView.DataSource

In the react native example, they give us this piece of code:

getInitialState: function() {
    return {
      dataSource: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
      }),
      loaded: false,
    };
  },

However, I can't seem to find any concise documentation describing rowHasChanged's functionality. Where do we get our two inputs, row1 and row2? What defines row1 and row2 in our ListView?

I've looked at the documentation for Listview here: http://facebook.github.io/react-native/docs/listview.html but I'm still not sure what defines rowHasChanged's inputs.

Upvotes: 9

Views: 7255

Answers (1)

gre
gre

Reputation: 1841

TL,DR; you have to define rowHasChanged related to the data you give to the data source.

  var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
  return {
    dataSource: ds.cloneWithRows(['row 1', 'row 2']),
  };

In this specific example, r1 and r2 will be a string because ds have 2 string rows as data.


It's up to you do define your own data format and to implement rowHasChanged according to this. rowHasChanged is basically called for each data source rows entry each time you change that data source rows, then only the rows that get changed are re-render (when rowHasChanged returned true).

More advanced example

Let's say I have this kind of data in my DataSource:

[
  { type: DOG, age: 12, name: "Snoopy" },
  { type: CAT, age: 13, name: "Oliver" },
  { type: HUMAN, age: 30, firstName: "Jerome", lastName: "Garcia" }
]

in my example format here, "type" is a mandatory field to switch the kind of data, "age" is a field available across all types, and then there is specific fields.

then I can implement rowHasChanged:

const rowHasChanged = (r1, r2) => {
  if (r1.type !== r2.type) return true;
  if (r1.age !== r2.age) return true;
  switch (r1.type) {
    case DOG:
    case CAT:
      return r1.name !== r2.name;
    case HUMAN:
      return r1.firstName !== r2.firstName || r1.lastName !== r2.lastName;
    default:
      throw new Error("Unsupported type "+r1.type);
  }
}

^ that way, a row only renders if it really changes according to my format.

(and you can imagine my renderRow function is something with a switch on type too)

Upvotes: 20

Related Questions