Как добавить / удалить элемент в ListView?

мы можем создать источник данных для ListView, как это

var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});  
var dataSource =  ds.cloneWithRows(['row 1', 'row 2']), };

но если я хочу добавить элементы или удалить элементы из источника данных, как я могу это сделать? Нужно ли всегда вызывать cloneWithRows с обновленным массивом?

2 ответов


да, вызова cloneWithRows(...)

родная документация React не охватывает ListViewDataSource объект, поэтому может быть полезно прочитать комментарии в исходный код чтобы увидеть, как это работает.

некоторые заметки, которые могут быть полезны:

  • cloneWithRows(data) немного ошибочно назван, потому что не просто создает клон данных, как предполагает имя.
  • вместо этого он пытается сравнить новый data строк с существующие строки (если есть) в источнике данных и выясняет, есть ли новые строки для вставки или существующие строки, которые необходимо заменить или удалить.

  • в комментариях к исходному коду обратите внимание, что данные в источнике данных неизменяемы по дизайну, поэтому правильным способом его изменения является указание обновленного источника данных, т. е. вызов cloneWithRows(...).

может показаться неинтуитивным передавать весь список, чтобы изменить несколько строк, но есть пара причины, почему это имеет смысл:

  • во-первых, он сочетается с общимархитектура на основе потока где основное внимание уделяется настройке состояний и позволяет компонентам выяснить, как мутировать себя, чтобы отразить новое состояние (подумайте о том, как this.props или this.state работает). Вы можете изменить массив данных, как вам нравится за пределами ListView компонент, но как только вы будете готовы обновить компонент, это достойный подход потока для передачи все состояние в компонент, чтобы он мог обновить себя.

  • во-вторых, это порядочно эффективный. ListView выполняет тяжелую дифференциацию строк в Javascript до он запускает процесс рендеринга, а затем отображает одну строку за раз (вы можете настройки этого) во время цикла рендеринга, чтобы уменьшить падение кадра.

  • в-третьих, ничто здесь не исключает возможности поддержки таких методов, как .addRow(..) in будущее. Дело в том, что текущая реализация не является плохим началом, потому что она предоставляет интерфейс на основе состояний, который позволяет разработчикам не беспокоиться о том, как компонент списка мутирует между состояниями.


Если вы посмотрите на расширенный пример фильмов из учебника React Native, он реализует поиск, который извлекает новые фильмы из удаленного API. Это означает, что каждый поиск будет обновлять хранилище данных, эффективно добавляя или удаляя элементы. Точное место, где это происходит, здесь:

getDataSource: function(movies: Array<any>): ListView.DataSource {
    return this.state.dataSource.cloneWithRows(movies);
}

https://github.com/facebook/react-native/blob/master/Examples/Movies/SearchScreen.js#L209

таким образом, похоже, что ваш способ является рекомендуемым методом.