React pattern stopping duplicate objects being added to state

Viewed 26

This is the current value of the state (myState):

[{“id”: 123, “title”: “book 1”}]

When a user tries to add a new book, I want to check if the Id matches any of the ids which are already in the state variable. I tried doing this:

if (!myState.map(a => a.id).includes(newBook.id)) setMyState([newBook, ...myState]);

This works fine but I don’t think it is the correct approach because the state update is asynchronous so the user might be able to add the same book twice if the state is not updated fast enough. What is the best pattern for these situations?

1 Answers

Yes, sure. Actually setState can receive a function, which the first prop is its own state value. You can do it like this:

// [{“id”: 123, “title”: “book 1”}]

if (!myState.map((a) => a.id).includes(newBook.id)) {
  setMyState((c) => ([newBook, ...c]));
}

It's fine to use myState as a comparison I guess.

But, if you're still too worried about it you can try an approach like this:

setMyState((c) => {
  if (!c.map((a) => a.id).includes(newBook.id)) {
    return ([newBook, ...c]));
  }
  return [...c] // or c (not sure if it'll work well with c only
  // anyway I'd prefer the first example above
}
Related