Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

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

Ответ 2

Если вы посмотрите пример расширенного фильма из учебника 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

Итак, похоже, что ваш способ - рекомендуемый метод.