Hallo zusammen,
Während ich an einigen Leistungsverbesserungen arbeitete, fand ich heraus, dass rowHasChanged
in keiner unserer Listen genannt wurde. Diese Listen sind endlos scrollende Listen, was bedeutet, dass, wenn Sie das Ende erreichen, mehr Elemente zum Anzeigen abgerufen und dann in die Liste abgelegt werden.
Es scheint, als würden alle Einträge in der Liste aktualisiert, wenn wir den Inhalt der DataSource ändern. Wir haben zwar ein shouldComponentUpdate
für alle Zeilen, aber wie ich rowHasChanged
verstanden habe, müssten diese Zeilen nicht erneut gerendert werden.
Ich habe ein einfaches Beispiel erstellt, das zeigt, wie wir Elemente an die Liste anhängen: https://gist.github.com/janmonschke/c9c84b6050683da0c64f
Was wir grundsätzlich tun ist:
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}
/>
);
}
Aber rowHasChanged
wird nie protokolliert.
Benutze ich es irgendwie falsch? Gibt es bessere Möglichkeiten, an eine ListView anzuhängen?
Gleiches Verhalten in 0.18.0
und 0.19.0
Hey Janmonschke, danke, dass du dieses Problem gemeldet hast!
Wie Sie wahrscheinlich schon gehört haben, wird React Native immer beliebter, und die Wahrheit ist, dass wir von der Aktivität, die es umgibt, ein wenig überwältigt werden. Es gibt einfach zu viele Probleme, als dass wir sie richtig handhaben könnten.
react-native
oder für weitere Echtzeit-Interaktionen auf Discord im #react-nativer Kanal.Okay, die Lösung gefunden in: http://stackoverflow.com/a/33871118.
Anscheinend ist es wichtig, von der richtigen DataSource-Instanz zu klonen;)
Der Code aus dem Kern sollte also lauten:
setData = [...setData, ...genRandomSet()];
this.setState({
dataSource: this.state.dataSource.cloneWithRows(setData)
});
Dies scheint ein Fehler zu sein, der sich leicht in Ihre Codebasis einschleicht. Ich frage mich, ob die korrekte Verwendung von DataSource
in der Dokumentation stärker betont werden sollte.
Danke @janmonschke! Ich stimme zu, ich hatte eine Reihe von Ansichten, die ständig neu gerendert wurden, und ich konnte nicht herausfinden, warum das passierte und warum die Funktion rowHasChanged
nie aufgerufen wurde. 👊
Hilfreichster Kommentar
Okay, die Lösung gefunden in: http://stackoverflow.com/a/33871118.
Anscheinend ist es wichtig, von der richtigen DataSource-Instanz zu klonen;)
Der Code aus dem Kern sollte also lauten:
Dies scheint ein Fehler zu sein, der sich leicht in Ihre Codebasis einschleicht. Ich frage mich, ob die korrekte Verwendung von
DataSource
in der Dokumentation stärker betont werden sollte.