9

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.

Randy Song
  • 574
  • 1
  • 7
  • 22

1 Answers1

20

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)

gre
  • 1,841
  • 2
  • 16
  • 26
  • Ah thanks that really helps! Just a bit more clarification... I'm still a little confused as to what we input into the function we define called "rowHasChanged" (that is, what exactly are the inputs to r1 and r2?) Is it, whenever there is an update to any of the rows within the DataSource, it will check r1 (the old row) against r2 to see if an actual change has occurred, and then re-renders? And is there any documentation on this? Thanks! – Randy Song Jan 12 '16 at 04:11
  • 1
    yeah exactly, the doc name "r1" and "r2" is weird but basically one is the old value and the other is the new value. I'm not sure this is very documented. – gre Jan 12 '16 at 09:01