31

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

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

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

4

2 に答える 2

64

はい、電話しますcloneWithRows(...)

React Native のドキュメントではオブジェクトについて説明していないため、ソース コードListViewDataSource内のコメントを読んで、これがどのように機能するかを確認することをお勧めします。

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

  • cloneWithRows(data)名前が示すようにデータのクローンを作成するだけではないため、少し誤解を招くような名前です。

  • data代わりに、新しい行を dataSource 内の既存の行 (存在する場合) と比較し、挿入する新しい行があるかどうか、または置換または削除する必要がある既存の行があるかどうかを判断します。

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

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

  • まず、React の全体的なフラックスベースのアーキテクチャと互換性があり、状態の設定に重点が置かれ、コンポーネントが新しい状態を反映するために自分自身を変更する方法を見つけられるようにします (どのように動作するthis.propsかを考えthis.stateてください)。コンポーネントの外部で好きなようにデータ配列を自由に変更ListViewできますが、コンポーネントを更新する準備ができたら、状態全体をコンポーネントに渡してコンポーネント自体を更新できるようにするのが適切なフラックス アプローチです。

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

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

于 2015-10-08T00:05:52.033 に答える
8

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

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

于 2015-03-30T17:16:12.640 に答える