Est-il possible de forcer un ListView à effectuer un nouveau rendu, même si les données de la source de données n'ont pas changé? J'ai un ListView dans une barre d'onglets de mon application et je souhaite le redessiner à chaque fois que cet onglet est sélectionné, que les données soient identiques ou aient été modifiées.
this.state = {
data: props.data,
dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
}
componentWillMount() {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(nextProps.data)
})
}
render() {
<ListView
dataSource={this.state.data}
renderRow={this._renderRow}
/>
}
J'ai essayé de jouer avec les arguments rowHasChanged
mais cela n'a pas aidé. Toute aide serait très appréciée
Donc, si j'ai bien compris, votre cas d'utilisation consiste à rendre à nouveau toutes les lignes de ListView en raison des modifications apportées à value
. Je ne sais pas ce qu'est value
, à vous de le déterminer, mais je vais utiliser value
pour expliquer ma réponse:
Il y a plusieurs façons de résoudre ce problème. chacun a ses avantages et ses inconvénients:
<ListView key={value} ... />
!! Il indique à React que ListView doit être rendu de nouveau lorsque la valeur change (il sera démonté, remonté).this.setState({
dataSource: new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !==
r2 }).cloneWithData(this.props.data)
});
value
et implémente correctement rowHasChanged. Par exemple: (r1, r2) => r1.value !== r2.value && r1.data !== r2.data
(<- C’EST JUSTE un moyen possible de représenter les données, vous devez choisir votre format, je suppose que vous avez cloné le source de données avec nextProps.data.map(data => ({ data, value })
).pour moi, la troisième et dernière solution est la meilleure parce que:
value
s)voici une autre réponse que j'ai donnée à ce sujet:
Quelles sont les entrées exactes de rowHasChanged dans ListView.DataSource
Le meilleur moyen de "mettre à jour" cela serait de cloner l'élément de données en question plutôt que de procéder à un hack d'indicateur, car le r1 !== r2
l'indique déjà. Au lieu de mettre à jour un élément individuel, modifiez le "pointeur" lui-même par clonage.
Pour ce problème particulier, mettez à jour l'élément dans le tableau comme suit.
arr[i] = { ...arr[i], someKey: newValue }
Cela remplacera la propriété "someKey" par "newValue" et la ligne actuelle aura un nouveau pointeur.
Voici une bonne ressource pour en savoir plus sur l'immuabilité dans JavaScript moderne qui réagit aux utilisations natives: https://wecodetheweb.com/2016/02/12/immutable-javascript-using-es6-and-beyond/
C’est probablement un peu exagéré, mais je remplace simplement la source de données sur composantDidUpdate (c’est peut-être mauvais pour les performances? Je ne sais pas, haha)
componentWillMount() {
this.ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});
this.dataSource = this.ds.cloneWithRows(this.props.shiftsList);
}
componentDidUpdate() {
this.ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});
this.dataSource = this.ds.cloneWithRows(this.props.shiftsList);
}
Je sais que je suis un peu en retard mais je suis sûr que cela reste d'actualité. Il existe une approche encore plus simple à cet égard ... Le premier exemple fourni par Jason est certainement une bonne solution, mais je pense à ceux qui s'embrouillent facilement. Si oui, utilisez ceci.
// On component initalization
componentWillMount() {
this.UpdateData();
}
// When the component updates
componentDidUpdate() {
if (this.state.data != this.props.data)
this.UpdateData();
}
// Function to update the ListView component data
UpdateData() {
var source = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.setState({
data: this.props.data,
dataSource: source.cloneWithRows(this.props.data)
});
}
Je recommande également d'implémenter Redux dans votre application. Ainsi, vous pouvez stocker la nouvelle valeur de tableau mise à jour dans un réducteur, puis la stocker localement dans un état et utiliser ultérieurement une instruction if dans la fonction composantDidUpdate pour déterminer si les données sont mises à jour ou non.
Le débogueur de React n'enregistre aucune plainte ni aucun avertissement basé sur les performances ...