From 628c8655302848fa9f48299f4c8ee5e2bf407e86 Mon Sep 17 00:00:00 2001 From: Masen Furer Date: Fri, 29 Mar 2024 09:41:18 -0700 Subject: [PATCH] Set is_hydrated=False at route onChangeStart (#2949) * Connection pulser only depends on has_connection_errors Avoid showing the WiFi error icon when the state is hydrating / navigating because not being hydrated is not indicative of a connection error in itself. * Set is_hydrated=False at route onChangeStart When navigation event starts, set is_hydrated=False on the client side before any on_load event is dispatched. This avoids a flickering problem where the client browser navigates and briefly shows content on the page before processing on_load events associated with the page. Fix #2885 * Update pyi --- reflex/.templates/web/utils/state.js | 3 +++ reflex/components/core/banner.py | 3 +-- reflex/components/core/banner.pyi | 1 - reflex/state.py | 4 +--- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/reflex/.templates/web/utils/state.js b/reflex/.templates/web/utils/state.js index a46f55d68..012ff0c3c 100644 --- a/reflex/.templates/web/utils/state.js +++ b/reflex/.templates/web/utils/state.js @@ -646,9 +646,12 @@ export const useEventLoop = ( // Route after the initial page hydration. useEffect(() => { + const change_start = () => dispatch["state"]({is_hydrated: false}) const change_complete = () => addEvents(onLoadInternalEvent()); + router.events.on("routeChangeStart", change_start); router.events.on("routeChangeComplete", change_complete); return () => { + router.events.off("routeChangeStart", change_start); router.events.off("routeChangeComplete", change_complete); }; }, [router]); diff --git a/reflex/components/core/banner.py b/reflex/components/core/banner.py index 2e634f55a..ea20179e1 100644 --- a/reflex/components/core/banner.py +++ b/reflex/components/core/banner.py @@ -17,7 +17,6 @@ from reflex.components.radix.themes.components.dialog import ( from reflex.components.radix.themes.layout import Flex from reflex.components.radix.themes.typography.text import Text from reflex.constants import Dirs, Hooks, Imports -from reflex.state import State from reflex.utils import imports from reflex.vars import Var, VarData @@ -199,7 +198,7 @@ class ConnectionPulser(Div): """ return super().create( cond( - ~State.is_hydrated | has_connection_errors, # type: ignore + has_connection_errors, WifiOffPulse.create(**props), ), position="fixed", diff --git a/reflex/components/core/banner.pyi b/reflex/components/core/banner.pyi index 89405518f..2972bd4d7 100644 --- a/reflex/components/core/banner.pyi +++ b/reflex/components/core/banner.pyi @@ -21,7 +21,6 @@ from reflex.components.radix.themes.components.dialog import ( from reflex.components.radix.themes.layout import Flex from reflex.components.radix.themes.typography.text import Text from reflex.constants import Dirs, Hooks, Imports -from reflex.state import State from reflex.utils import imports from reflex.vars import Var, VarData diff --git a/reflex/state.py b/reflex/state.py index 92c3ca5a3..d46e61439 100644 --- a/reflex/state.py +++ b/reflex/state.py @@ -1835,11 +1835,9 @@ class OnLoadInternalState(State): # Do not app.compile_()! It should be already compiled by now. app = getattr(prerequisites.get_app(), constants.CompileVars.APP) load_events = app.get_load_events(self.router.page.path) - if not load_events and self.is_hydrated: - return # Fast path for page-to-page navigation if not load_events: self.is_hydrated = True - return # Fast path for initial hydrate with no on_load events defined. + return # Fast path for navigation with no on_load events defined. self.is_hydrated = False return [ *fix_events(