web-dev-qa-db-ja.com

ListViewにアイテムを追加/削除する方法は?

このようにListViewのデータソースを作成できます

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

しかし、アイテムを追加したり、データソースからアイテムを削除したい場合、どうすればよいですか?更新された配列で常にcloneWithRowsを呼び出す必要がありますか?

30
thecodejack

はい、cloneWithRows(...)を呼び出します

ReactネイティブドキュメントはListViewDataSourceオブジェクトをカバーしていないため、 ソースコードのコメントを読むと役立つ場合があります これがどのように機能するかを確認します。

役に立つかもしれないいくつかのメモ:

  • cloneWithRows(data)は、名前が示すようにデータのクローンを作成するだけではないため、少し誤解を招く名前が付けられています。
  • 代わりに、新しいdata行をdataSourceの既存の行(存在する場合)と比較し、挿入する新しい行があるか、置換または削除する必要がある既存の行があるかどうかを調べます。

  • ソースコードのコメントでは、データソース内のデータは設計上不変であるため、変更する正しい方法は、更新されたデータソースを指定する、つまりcloneWithRows(...)を呼び出すことです。

いくつかの行を変更するためだけにリスト全体を渡すのは直感的ではないように思えるかもしれませんが、それが理にかなっている理由はいくつかあります。

  • まず、Reactの全体的な フラックスベースのアーキテクチャに適合します 状態の設定に焦点を当て、コンポーネントが新しい状態を反映するように自分自身を変更する方法を見つけられるようにします(_this.props_または_this.state_は機能します)。 ListViewコンポーネントの外で好きなようにデータ配列を自由に変更できますが、コンポーネントを更新する準備ができたら、状態全体をコンポーネントに渡してそれ自体を更新できるのはまともな方法です。

  • 第二に、それはまともな効率です。 ListViewは、Javascriptbeforeで重い行の区別を行い、レンダリングプロセスを開始してから、一度に1行をレンダリングします( レンダリングサイクル中にこれを調整して )、フレームドロップを減らします。

  • 第三に、将来の.addRow(..)のようなメソッドをサポートする可能性を妨げるものはありません。ポイントは、現在の実装は悪いスタートではないということです。これは、開発者がリストコンポーネントが状態間でどのように変化するかを心配することを可能にする状態ベースのインターフェイスを提供するためです。

64
tohster

React Nativeチュートリアルの拡張されたMoviesの例を見ると、リモート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

したがって、あなたの方法が推奨される方法のようです。

8
Colin Ramsay