redux-toolkit
redux-toolkit copied to clipboard
upsertMany with multiple updates with the same id throws away updates
I'm using upsertMany to push multiple updates with the same id. If the id previously didn't exist only the last update in the array of updates is added to the store. Example using the books example from the createEntityAdapter documentation https://redux-toolkit.js.org/api/createEntityAdapter:
const booksAdapter = createEntityAdapter({
selectId: (book) => book.customId,
sortComparer: (a, b) => (a.customId > b.customId ? 1 : -1)
});
const booksSlice = createSlice({
name: "books",
initialState: booksAdapter.getInitialState(),
reducers: {
booksUpserted: booksAdapter.upsertMany,
}
});
const { booksUpserted } = booksSlice.actions;
const store = configureStore({
reducer: {
books: booksSlice.reducer
}
});
store.dispatch(booksUpserted([
{ customId: "a", title: "First" },
{ customId: "a", author: "Author" },
{ customId: "a", description: "Description" }
])
);
After dispatching dispatching I expected the state to look like this:
{"ids":["a"],"entities":{"a":{"customId":"a", title: "First", author: "Author", "description":"Description"}}}
Instead it looks like this:
{"ids":["a"],"entities":{"a":{"customId":"a","description":"Description"}}}
I created a codesandbox example to demonstrate the issue https://codesandbox.io/s/upsertmany-test-lwmfy4?file=/src/App.js
Hmm. Currently the logic is:
function upsertManyMutably(
newEntities: readonly T[] | Record<EntityId, T>,
state: R
): void {
const [added, updated] = splitAddedUpdatedEntities<T>(
newEntities,
selectId,
state
)
updateManyMutably(updated, state)
addManyMutably(added, state)
}
I wonder what would happen if we just flip the update and add steps?
probably the same - the splitAddedUpdatedEntities only checks if they're in the current state, not the state after each update has been applied
all of the entries get counted as "added" and therefore only the first takes effect
Ah, good point. (Been a while since I've looked at this code :) )
Not immediately sure what a good solution is here without digging into it further.
@markerikson any updates on this?
@dlarroder there's been no comments since I wrote one a year ago, and the issue is still open, so no :)