Wiem, że zostało to wcześniej zadane, zobacz na przykład here, here i here.React Native ListView: Błędny wiersz usunięty podczas usuwania
Jednak żadna z odpowiedzi/komentarzy nie jest zadowalająca. Albo każą ci sklonować dane, które nie rozwiążą problemu, albo ustawić unikalny klucz w ListView, który rozwiązuje problem, ale tworzy nowy.
Po ustawieniu unikalnego klucza na liście i zaktualizowaniu go po usunięciu cały widok jest renderowany ponownie i przewija się do góry. Użytkownik, który przewija listę w dół, aby usunąć przedmiot, oczekuje, że lista utrzyma jego pozycję.
Oto wymyślony przykład, wykorzystując to, co zakładam był poprawny sposób klonowanie danych:
var ListViewExample = React.createClass({
getInitialState() {
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => {
r1 !== r2
}});
var rows = ['row 1', 'row 2', 'row 3'];
return {
dataSource: ds.cloneWithRows(rows),
};
},
_deleteRow() {
var rows = ['row 1', 'row 3'];
this.setState({dataSource: this.state.dataSource.cloneWithRows(rows)})
},
renderRow(rowData, sectionID, rowID) {
return <TouchableOpacity onPress={this._deleteRow}
style={{height: 60, flex: 1, borderBottomWidth: 1}}>
<Text>{rowData}</Text>
</TouchableOpacity>
},
render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
/>
);
}
});
I here widać gif go w akcji, gdzie zły rząd get usunięty. Alternatywą, aby ustawić podpórkę key
ListView, usuwa się prawidłowy wiersz, ale jak już powiedziałem, spowoduje to przewinięcie listy do góry.
UPDATE
Ja już zaakceptowane odpowiedź Nader jest poniżej, ale to nie wydaje się być właściwa droga, ponieważ nie wymaga rowHasChanged
na DataSource. To także nie jest zgodne z dokumentacją ListView. To nie rozwiąże mój problem więc zostawię to zaznaczone jako odpowiedź, ale mam wrażenie, że jest to obejście zamiast poprawne rozwiązanie
Kolejna aktualizacja
Dobrze jest to niewygodne, ale moim zadaniem było rowHasChanged
brakuje instrukcji return
. Wydaje mi się, że za dużo cukru ES6 w mojej kawie.
Podsumowując, jeśli zepsujesz swoją funkcję rowHasChanged
, z jakiegoś powodu zadziała this._ds
. Jeśli robić rzeczy we właściwy sposób, aby rozpocząć z was prawdopodobnie powinien użyć czegoś takiego:
this.setState({
dataSource: this.state.dataSource.cloneWithRows(rows)
});
podczas aktualizacji dataSource
.
Pamiętaj również, że potrzebujesz nowej datablob rows
. Mutowanie go na miejscu z czymś takim, jak cloneWithRows(rows.push(newRow)
nie zadziała, podczas gdy cloneWithRows(rows.concat([newRow])
będzie działać.
Jeśli to pomoże ktoś inny ... kluczem dla mnie robił głęboki kopię mojej liście przed klonowanie ... więc przed cloneWithRows zrobić new_rows = [... wiersze] –