React-native: `rowHasChanged`とListViewレンダリングに関する混乱

作成日 2016年02月04日  ·  3コメント  ·  ソース: facebook/react-native

やあみんな、

いくつかのパフォーマンスの改善に取り組んでいるときに、 rowHasChangedがどのリストでも呼び出されていないことがわかりました。 これらのリストは無限スクロールリストです。つまり、最後に到達すると、表示するアイテムがさらにフェッチされ、リストにダンプされます。

データソースのコンテンツを変更するたびに、リスト内のすべてのエントリが更新されるようです。 すべての行にshouldComponentUpdateがありますが、 rowHasChangedを理解したことから、これらの行を再度レンダリングする必要はありません。

リストにアイテムを追加する方法を示す簡単な例を作成しました: https ://gist.github.com/janmonschke/c9c84b6050683da0c64f

基本的に行うことは次のとおりです。

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}
    />
  );
}

ただし、 rowHasChangedはログに記録されません。

どういうわけか間違った使い方をしていますか? ListViewに追加するより良い方法はありますか?

0.18.00.19.0で同じ動作

Locked

最も参考になるコメント

さて、 http://stackoverflow.com/a/33871118で解決策を見つけました。

どうやら、正しいDataSourceインスタンスからクローンを作成することが重要です;)

したがって、要点からのコードは次のようになっているはずです。

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

これは、コードベースに簡単に潜入しているエラーのようです。 DataSourceの正しい使用法は、ドキュメントでもっと強調されるべきかどうか疑問に思います。

全てのコメント3件

こんにちはjanmonschke、この問題を報告してくれてありがとう!

おそらく聞いたことがあると思いますが、React Nativeは非常に人気があり、真実はそれを取り巻く活動に少し圧倒されているということです。 適切に管理するには問題が多すぎます。

  • 何かを行う方法がわからない、または何かが期待どおりに機能していないが、それがバグであるかどうかわからない場合は、タグreact-nativeを付けてStackOverflowで質問するか、よりリアルタイムのやり取りについては、 Discordで質問してください。 #react-ネイティブチャンネル。
  • これが機能のリクエストまたは修正したいバグである場合は、製品の問題について報告してください。 コミュニティが経験している最も重要な問題に焦点を当てることができるランキング機能があります。
  • 詳細な議論の準備ができている明確な問題とPRを歓迎します。 必要に応じてスクリーンショットを提供し、使用しているReactNativeのバージョンを常に記載してください。 貢献していただきありがとうございます!

さて、 http://stackoverflow.com/a/33871118で解決策を見つけました。

どうやら、正しいDataSourceインスタンスからクローンを作成することが重要です;)

したがって、要点からのコードは次のようになっているはずです。

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

これは、コードベースに簡単に潜入しているエラーのようです。 DataSourceの正しい使用法は、ドキュメントでもっと強調されるべきかどうか疑問に思います。

ありがとう@janmonschke! 私は同意します。私は絶えず再レンダリングするビューをたくさん持っていて、なぜそれが起こっているのか、そしてなぜrowHasChanged関数が呼び出されなかったのか理解できませんでした。 👊

このページは役に立ちましたか?
0 / 5 - 0 評価