Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the exact inputs to rowHasChanged in ListView.DataSource

Tags:

react-native

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.

like image 945
Randy Song Avatar asked Jan 11 '16 06:01

Randy Song


1 Answers

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)

like image 128
gre Avatar answered Oct 22 '22 13:10

gre