Skip to content

Immer 11 breaking optimistic updates #5159

@JacobJaffe

Description

@JacobJaffe

Hi, I've encountered a very weird bug.

I have reproduced this behavior on rtk 2.9 and 2.11.
When locking immer to 10.0.3, the bug is fixed, on both rtk versions.

Basically, it looks like draft updates aren't being correctly applied under cases with nested array data.

For example, I have this optimistic update group:

const markNotificationReadInCache = ({
  id,
  uid,
}: {
  id: string;
  uid: string;
}) => {
   const notificationListPatch = notificationsApi.util.updateQueryData(
    "getNotifications",
    { uid },
    (draft) => {
      for (const page of draft.pages) {
        const notif = page.notifications.find((n) => n.id === id);
        if (notif) {
          notif.readAt = Date.now();
          break;
        }
      }
    },
  );
  const userPatch = usersApi.util.updateQueryData(
    "getUser",
    { uid },
    (draft) => {
      draft.unreadNotificationsCount = Math.max(
        0,
        draft.unreadNotificationsCount - 1,
      );
    },
  );
  return [notificationListPatch, userPatch];
};

In this patch group, the userPatch is working as expected. The notificationListPatch, however, isn't, and the notifications aren't getting updated.

I have a few other cases where this same thing is happening.

For example, I have this scenario, where I optimistically patch comments in a discussion thread:

  const patchThreads = threadsApi.util.updateQueryData(
    "getThreads",
    {
      id: thread.post.id,
      uid: thread.post.uid,
    },
    (draft) => {
      const foundThread = draft.find((t) => t.id === thread.id);
      if (foundThread) {
        foundThread.numReplies += 1;
        foundThread.replies.push(optimisticThreadReply);
      }
    },
  );

Here, something very strange is occurs: the top-level array, (draft itself) gets an item added to it, rather than the nested entry.


Further, this only occurs in my production application. I've isolated this to NODE_ENV==="production", rather than something else happening in my CD pipeline.

Taking a quick look into the shipped immer.mjs, there do look to be some code branches based off of that, but this is pretty out of my depth of debugging now.


TLDR:

  • Immer 10 -> 11 breaks array draft updates in updateQueryData
  • Occurs in all recent versions of rtk
  • only occurs when NODE_ENV===production
  • force resolving immer version to 10.0.3 seems to fix this for me, though there may be a compatibility issue with the major version change that'll bite...

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions