Skip to content

RTK Query subscriptions do not update in React portals rendered into a new window #5085

@HMemmi

Description

@HMemmi

What I’m doing

I’m building a feature where the user can “pop out” a panel into a new browser window.
I create the new window and render React content into it via createPortal:

const [container, setContainer] = useState(null);
const [panelWindow, setPanelWindow] = useState(null);

useEffect(() => {
  const popup = window.open("", "_blank", "width=600,height=800");
  if (!popup) return;

  const el = popup.document.createElement("div");
  popup.document.body.appendChild(el);

  setPanelWindow(popup);
  setContainer(el);

  return () => popup.close();
}, []);

if (!container || !panelWindow) return null;

//wrapped by the same Redux <Provider>
return createPortal(
  <Panel />,
  container
);

The Panel contains RTK Query hooks (useGetXQuery, useMutation, etc.) that subscribe to data.

What works
• If I use vanilla Redux slices (dispatch / useSelector), the panel updates correctly in the new window.
• If I use axios + useState, it also works fine.
• RTK Query mutations (usePatchSomethingMutation) dispatch correctly and update the cache.
• Redux DevTools shows the cache entry as updated and fulfilled.

What breaks
• Components rendered into the new window with RTK Query hooks (useGetXQuery) do not re-render when the cache updates.
• debugValue inside the hook shows the updated data (e.g. 39 rows), but data / currentData in the component remain stale (e.g. 38 rows).
• If I force any re-render (resizing, dispatching a dummy action, or making the main window visible by even a single pixel), the panel updates immediately with the correct data.
• This only happens when the new window is maximized; if the main window is visible even slightly or the popup is resized, the panel updates immediately.

Why I think this is happening
• RTK Query hooks rely on useSyncExternalStore subscriptions.
• useSyncExternalStore seems tied to the main document visibility/focus for scheduling updates.
• Since the component tree is portaled into a different window.document, subscriptions don’t flush updates until the main document becomes visible again.
• Plain Redux works because reducers just update state immediately, without visibility checks.

Steps to reproduce

  1. Render an RTK Query-enabled component into a new window using createPortal.
  2. Maximize the new window.
  3. Trigger a mutation that updates the cached query data.
  4. Observe: DevTools shows the cache updated, but the new window UI does not.
  5. Force a re-render (resize window, dispatch dummy action, show main document). Now the new window updates.

Expected behavior
RTK Query subscriptions should notify and re-render components in any window as long as they are part of the same React tree + Redux store. Visibility of the original document should not matter.

Workarounds tried
• refetch() → does not help.
• Dispatching a dummy action → works, but hacky.
• Separate React root in popup with → still broken for RTK Query (but plain Redux works fine).

Environment
• React 19.1.0
• Redux Toolkit 2.9.0
• Browser: Chrome (latest), also reproduced in Firefox

Here is a minimal reproducible example: https://codesandbox.io/p/sandbox/zpqhcz

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions