React-native: Confusion à propos de `rowHasChanged` et du rendu ListView

Créé le 4 févr. 2016  ·  3Commentaires  ·  Source: facebook/react-native

Salut à tous,

En travaillant sur certaines améliorations de performances, j'ai découvert que rowHasChanged n'était appelé dans aucune de nos listes. Ces listes sont des listes à défilement infini, ce qui signifie que lorsque vous atteignez la fin, il récupère plus d'éléments à afficher, puis les place dans la liste.

Il semble que toutes les entrées de la liste soient mises à jour chaque fois que nous modifions le contenu de la source de données. Nous avons un shouldComponentUpdate en place pour toutes les lignes, mais d'après ce que j'ai compris rowHasChanged , ces lignes n'auraient pas besoin d'être rendues à nouveau.

J'ai créé un exemple simple qui montre comment nous ajoutons des éléments à la liste : https://gist.github.com/janmonschke/c9c84b6050683da0c64f

Ce que nous faisons essentiellement, c'est :

constructor() {
  // (...)
  this.ds = new ListView.DataSource({rowHasChanged: (r1, r2) => {
    console.log('rowHasChanged');
    return r1 !== r2;
  }});
  // (...)
}

onEndReached = () => {
  // append data to the end
  setData = [...setData, ...genRandomSet()];
  this.setState({
    dataSource: this.ds.cloneWithRows(setData)
  });
  console.log('onEndReached');
};

render() {
  return (
    <ListView
      dataSource={this.state.dataSource}
      renderRow={this.renderRow}
      onEndReached={this.onEndReached}
    />
  );
}

Mais rowHasChanged n'est jamais enregistré.

Est-ce que je l'utilise d'une manière ou d'une autre d'une manière incorrecte ? Existe-t-il de meilleures façons d'ajouter à un ListView ?

Même comportement dans 0.18.0 et 0.19.0

Locked

Commentaire le plus utile

D'accord, j'ai trouvé la solution dans : http://stackoverflow.com/a/33871118.

Apparemment, il est important de cloner à partir de la bonne instance DataSource ;)

Donc, le code de l'essentiel aurait dû être :

  setData = [...setData, ...genRandomSet()];
  this.setState({
    dataSource: this.state.dataSource.cloneWithRows(setData)
  });

Cela ressemble à une erreur qui se faufile facilement dans votre base de code. Je me demande si l'utilisation correcte de DataSource devrait être davantage soulignée dans la documentation.

Tous les 3 commentaires

Hé janmonschke, merci d'avoir signalé ce problème !

React Native, comme vous l'avez probablement entendu, devient très populaire et la vérité est que nous sommes un peu dépassés par l'activité qui l'entoure. Il y a tout simplement trop de problèmes pour que nous puissions les gérer correctement.

  • Si vous ne savez pas comment faire quelque chose ou si quelque chose ne fonctionne pas comme prévu mais que vous n'êtes pas sûr que ce soit un bogue , veuillez demander sur StackOverflow avec la balise react-native ou pour plus d'interactions en temps réel, demandez sur Discord dans le #react-canal natif.
  • S'il s'agit d'une demande de fonctionnalité ou d'un bogue que vous souhaitez voir corrigé, veuillez le signaler sur Product Pains . Il a une fonction de classement qui nous permet de nous concentrer sur les problèmes les plus importants rencontrés par la communauté.
  • Nous accueillons les questions claires et les relations publiques prêtes pour une discussion approfondie. Veuillez fournir des captures d'écran le cas échéant et toujours mentionner la version de React Native que vous utilisez. Merci pour vos contributions!

D'accord, j'ai trouvé la solution dans : http://stackoverflow.com/a/33871118.

Apparemment, il est important de cloner à partir de la bonne instance DataSource ;)

Donc, le code de l'essentiel aurait dû être :

  setData = [...setData, ...genRandomSet()];
  this.setState({
    dataSource: this.state.dataSource.cloneWithRows(setData)
  });

Cela ressemble à une erreur qui se faufile facilement dans votre base de code. Je me demande si l'utilisation correcte de DataSource devrait être davantage soulignée dans la documentation.

Merci @janmonschke ! Je suis d'accord, j'avais un tas de vues constamment restituées et je ne pouvais pas comprendre pourquoi cela se produisait et pourquoi la fonction rowHasChanged n'était jamais appelée. 👊

Cette page vous a été utile?
0 / 5 - 0 notes