Ver código fonte

Prepend hydrate event when connecting (#4929)

* Prepend hydrate event when connecting

Avoid backend on_mount events triggering a `reload` message, which ends up
requeuing hydrate event.

* Use .shift instead of .pop

* processEvent takes care of socket not being connected
Masen Furer 2 meses atrás
pai
commit
debc5bbcd9
1 arquivos alterados com 12 adições e 6 exclusões
  1. 12 6
      reflex/.templates/web/utils/state.js

+ 12 - 6
reflex/.templates/web/utils/state.js

@@ -352,8 +352,13 @@ export const applyRestEvent = async (event, socket) => {
  * Queue events to be processed and trigger processing of queue.
  * Queue events to be processed and trigger processing of queue.
  * @param events Array of events to queue.
  * @param events Array of events to queue.
  * @param socket The socket object to send the event on.
  * @param socket The socket object to send the event on.
+ * @param prepend Whether to place the events at the beginning of the queue.
  */
  */
-export const queueEvents = async (events, socket) => {
+export const queueEvents = async (events, socket, prepend) => {
+  if (prepend) {
+    // Drain the existing queue and place it after the given events.
+    events = [...events, ...Array.from({length: event_queue.length}).map(() => event_queue.shift())];
+  }
   event_queue.push(...events);
   event_queue.push(...events);
   await processEvent(socket.current);
   await processEvent(socket.current);
 };
 };
@@ -477,7 +482,7 @@ export const connect = async (
   });
   });
   socket.current.on("reload", async (event) => {
   socket.current.on("reload", async (event) => {
     event_processing = false;
     event_processing = false;
-    queueEvents([...initialEvents(), event], socket);
+    queueEvents([...initialEvents(), event], socket, true);
   });
   });
 
 
   document.addEventListener("visibilitychange", checkVisibility);
   document.addEventListener("visibilitychange", checkVisibility);
@@ -773,16 +778,17 @@ export const useEventLoop = (
   const sentHydrate = useRef(false); // Avoid double-hydrate due to React strict-mode
   const sentHydrate = useRef(false); // Avoid double-hydrate due to React strict-mode
   useEffect(() => {
   useEffect(() => {
     if (router.isReady && !sentHydrate.current) {
     if (router.isReady && !sentHydrate.current) {
-      const events = initial_events();
-      addEvents(
-        events.map((e) => ({
+      queueEvents(
+        initial_events().map((e) => ({
           ...e,
           ...e,
           router_data: (({ pathname, query, asPath }) => ({
           router_data: (({ pathname, query, asPath }) => ({
             pathname,
             pathname,
             query,
             query,
             asPath,
             asPath,
           }))(router),
           }))(router),
-        }))
+        })),
+        socket,
+        true,
       );
       );
       sentHydrate.current = true;
       sentHydrate.current = true;
     }
     }