このような状態が与えられた場合:
state = {
things: [
{ id: 'a1', name: 'thing 1' },
{ id: 'a2', name: 'thing 2' },
],
};
ID「a1」が削除された新しい状態を作成するにはどうすればよいですか?新しいアイテムをプッシュするのは簡単です:
return state.set(state.get('things').Push(newThing));
しかし、id
プロパティによってオブジェクトを検索して削除する方法がわかりません。私はこれを試しました:
return state.set('tracks',
state.get('tracks').delete(
state.get('tracks').findIndex(x => x.get('id') === 'a2')
)
)
しかし、面倒であるように見えます。さらに、findIndex
が-1
を返す場合、それはdelete
の有効な値であるため、アイテムが見つかった場合にのみ機能します。
return state.set('things', state.get('things').filter(o => o.get('id') !== 'a1'));
フィルタを使用している場合、すべてのサイクルを繰り返します-> 1つの効果的な方法は、インデックス=>スライスを見つけてスプリッタを使用することです...
const index = state.findIndex(data => data.id === action.id);
return [...state.slice(0, index), ...state.slice(index + 1)];
または、「検索してから削除する」ため...
var itemIndex = this.state.get("tracks").findIndex(x => x.get('id') === 'a2');
return itemIndex > -1 ? this.state.deleteIn(["tracks", itemIndex]) : this.state;
これにより、変更がない場合に状態が変化しないことが保証されます。
Immutablejsは素晴らしいですが、同時にいくつかのEdgeのケースでは事態をより複雑にします特にネストされた配列を扱う場合。
この特定の問題について、一般的な意味でJSに戻す方が簡単な場合があります。
// 1. get a copy of the list into normal JavaScript
const myList = state.getIn(['root', 'someMap', 'myList']).toJS()
// 2. remove item in list using normal JavaScript and/or anything else
myList.splice(deleteIndex, 1)
// 3. return the new state based on mutated myList
return state
.mergeDeep({ root: { someMap: { myList: undefined } }})
.mergeDeep({ root: { someMap: { myList } }})
残念なことに、単にundefined
を配列値として直接設定すると、ImmutableJSは現在のリスト間の値の比較を行い、それらを変更するだけで奇妙なものになるため、ステップ3はmyList
に特に設定する必要があります動作。
これはメンタルオーバーヘッドを単純化するための正当化です。ループでこれを行うことはお勧めしません。むしろ、手順3の前でなければならない場合、ループで純粋なJS配列を操作します。
同様のタスクの解決策を探しているときに、このスレッドを見つけました。 pdate メソッドで解決しました:
return state.update('things', (things) => things.filter((t) => t.id !== action.things.id))
より良い/好まれるアイデア/コメントはありますか?
Immutable.jsがなくても、次の関数でそれを行うことができます。
function arrayFilter(array, filter) {
let ret = array
let removed = 0
for (let index = 0; index < array.length; index++) {
const passed = filter(array[index], index, array)
if (!passed) {
ret = [...ret.slice(0, index - removed), ...ret.slice(index - removed + 1)]
removed++
}
}
return ret
}