Skip to content

Commit 15b379f

Browse files
demyanmdmelnik
andauthored
fix(entityAdapter): ensure sorted setMany keeps just one ID in state.ids after applying multiple entities with the same ID (#5107)
Co-authored-by: dmelnik <demyan.melnik@aporia.su>
1 parent fd39b8e commit 15b379f

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

packages/toolkit/src/entities/sorted_state_adapter.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,16 @@ export function createSortedStateAdapter<T, Id extends EntityId>(
9393
newEntities: readonly T[] | Record<Id, T>,
9494
state: R,
9595
): void {
96+
let deduplicatedEntities = {} as Record<Id, T>;
9697
newEntities = ensureEntitiesArray(newEntities)
9798
if (newEntities.length !== 0) {
9899
for (const item of newEntities) {
99-
delete (state.entities as Record<Id, T>)[selectId(item)]
100+
const entityId = selectId(item);
101+
// For multiple items with the same ID, we should keep the last one.
102+
deduplicatedEntities[entityId] = item;
103+
delete (state.entities as Record<Id, T>)[entityId]
100104
}
105+
newEntities = ensureEntitiesArray(deduplicatedEntities);
101106
mergeFunction(state, newEntities)
102107
}
103108
}

packages/toolkit/src/entities/tests/sorted_state_adapter.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,25 @@ describe('Sorted State Adapter', () => {
607607
expect(withOneSorted).toEqual(withOneUnsorted);
608608
})
609609

610+
it('should work consistent with Unsorted State Adapter adding duplicate ids', () => {
611+
const unsortedAdaptor = createEntityAdapter({
612+
selectId: (book: BookModel) => book.id
613+
});
614+
615+
const firstEntry = {id: AClockworkOrange.id, author: TheHobbit.author }
616+
const secondEntry = {id: AClockworkOrange.id, title: 'Zack' }
617+
const withNothingSorted = adapter.setAll(state, [TheHobbit]);
618+
const withNothingUnsorted = unsortedAdaptor.setAll(state, [TheHobbit]);
619+
const withOneSorted = adapter.setMany(withNothingSorted, [
620+
{ ...AClockworkOrange, ...firstEntry, id: 'th' }, {...AClockworkOrange, ...secondEntry, id: 'th'}
621+
])
622+
const withOneUnsorted = unsortedAdaptor.setMany(withNothingUnsorted, [
623+
{ ...AClockworkOrange, ...firstEntry, id: 'th' }, {...AClockworkOrange, ...secondEntry, id: 'th'}
624+
])
625+
626+
expect(withOneSorted).toEqual(withOneUnsorted);
627+
})
628+
610629
it('should let you set many entities in the state when passing in a dictionary', () => {
611630
const changeWithoutAuthor = { id: TheHobbit.id, title: 'Silmarillion' }
612631
const withMany = adapter.setAll(state, [TheHobbit])

0 commit comments

Comments
 (0)