イベントハンドラ関数が受け取ったオブジェクトのリストを表示するListViewを作成しようとしています。オブジェクトは非同期的に1度に1つ受信されます(ListViewDataSource documentationのシナリオに似ています)。非同期に更新されたオブジェクトのリストビュー
各オブジェクトには、IDフィールドと値フィールドがあります(特にこのフィールドには関係ありません)。 ListViewは各オブジェクトの両方のフィールドを表示します。
ハンドラは、IDは同じで値は異なる複数のオブジェクトを受け取ることができます。この場合、ListViewは新しい値でエントリを更新する必要があります。
ListViewに新しい項目を挿入するとうまくいきますが、既存の項目を更新するのではありません。どうやってするの?
今後の質問:ListViewの要素を値フィールドで並べ替えるにはどうすればよいですか?それを行う最善の方法は何ですか?
オブジェクトの疑似(ISH)コード:コンポーネントの
class DataObj {
objid: string;
value: string;
static create(rawData: string) : ?DataObj {
if (Invalid data) return null;
let dataObj = new DataObj();
dataObj.objid = ...;
dataObj.value = ...;
return dataObj;
}
static equal(lhs: DataObj, rhs: DataObj) {
return (lhs.objid === rhs.objid && lhs.value === rhs.value);
}
}
コード:以下のように
type State = {
items: ListView.DataSource,
};
class MyComponent extends React.Component {
state: State;
_items = {};
constructor(props: Props, context: {}) {
super(props, context);
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => !DataObj.equal(r1, r2)
});
this.state = {
items: ds.cloneWithRows(this._items),
};
}
_onNewItem = async (rawData: string) => {
const newItem = DataObj.create(rawData);
if (newItem) {
// Valid item
let oldItem = this._items[newItem.objid];
if (!old || !DataObj.equal(oldItem, newItem)) {
// New item or updated item
// Clone _items, since it must be immutable, and add new item to it.
let newItems = Object.assign({}, this._items);
newItems[newItem.objid] = newItem;
// update _items reference to its modified clone.
this._items = newItems;
// Update the state
this.setState(({items}) => ({
items: items.cloneWithRows(newItems),
}));
}
}
};
render(): React.Element<*> {
return (
<ListView
dataSource={this.state.items}
enableEmptySections={true}
renderRow={this._renderDataObj} />
);
}
_renderDataObj = (
obj: DataObj,
sectionID: number,
rowID: number
) : React.Element<*> => {
return (
<DataObjRenderer
key={obj.objid}
objid={obj.objid}
value={obj.value}
/>
);
}
}
実際には配列がソートされます。フォローアップの質問は、マップを使用してオブジェクトを格納し、必要に応じてオブジェクトを更新することです。それから、Array.from(this._items.values())という項目を持つ配列を取得する必要があります。それを並べ替える。しかしそれは別の問題を引き起こします:ReactはDataObjectのプロパティを変更すると無視します。 ListView要素のキーにすべての "observable"プロパティを追加しようとしました。しかし、それはうまく動作しません。 – Marcus