やあみんな、
いくつかのパフォーマンスの改善に取り組んでいるときに、 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.0
と0.19.0
で同じ動作
こんにちはjanmonschke、この問題を報告してくれてありがとう!
おそらく聞いたことがあると思いますが、React Nativeは非常に人気があり、真実はそれを取り巻く活動に少し圧倒されているということです。 適切に管理するには問題が多すぎます。
react-native
を付けてStackOverflowで質問するか、よりリアルタイムのやり取りについては、 Discordで質問してください。 #react-ネイティブチャンネル。さて、 http://stackoverflow.com/a/33871118で解決策を見つけました。
どうやら、正しいDataSourceインスタンスからクローンを作成することが重要です;)
したがって、要点からのコードは次のようになっているはずです。
setData = [...setData, ...genRandomSet()];
this.setState({
dataSource: this.state.dataSource.cloneWithRows(setData)
});
これは、コードベースに簡単に潜入しているエラーのようです。 DataSource
の正しい使用法は、ドキュメントでもっと強調されるべきかどうか疑問に思います。
ありがとう@janmonschke! 私は同意します。私は絶えず再レンダリングするビューをたくさん持っていて、なぜそれが起こっているのか、そしてなぜrowHasChanged
関数が呼び出されなかったのか理解できませんでした。 👊
最も参考になるコメント
さて、 http://stackoverflow.com/a/33871118で解決策を見つけました。
どうやら、正しいDataSourceインスタンスからクローンを作成することが重要です;)
したがって、要点からのコードは次のようになっているはずです。
これは、コードベースに簡単に潜入しているエラーのようです。
DataSource
の正しい使用法は、ドキュメントでもっと強調されるべきかどうか疑問に思います。