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
This commit is contained in:
Masen Furer 2024-03-29 09:41:18 -07:00 committed by GitHub
parent ee66884e96
commit 628c865530
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 5 additions and 6 deletions

View File

@ -646,9 +646,12 @@ export const useEventLoop = (
// Route after the initial page hydration. // Route after the initial page hydration.
useEffect(() => { useEffect(() => {
const change_start = () => dispatch["state"]({is_hydrated: false})
const change_complete = () => addEvents(onLoadInternalEvent()); const change_complete = () => addEvents(onLoadInternalEvent());
router.events.on("routeChangeStart", change_start);
router.events.on("routeChangeComplete", change_complete); router.events.on("routeChangeComplete", change_complete);
return () => { return () => {
router.events.off("routeChangeStart", change_start);
router.events.off("routeChangeComplete", change_complete); router.events.off("routeChangeComplete", change_complete);
}; };
}, [router]); }, [router]);

View File

@ -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.layout import Flex
from reflex.components.radix.themes.typography.text import Text from reflex.components.radix.themes.typography.text import Text
from reflex.constants import Dirs, Hooks, Imports from reflex.constants import Dirs, Hooks, Imports
from reflex.state import State
from reflex.utils import imports from reflex.utils import imports
from reflex.vars import Var, VarData from reflex.vars import Var, VarData
@ -199,7 +198,7 @@ class ConnectionPulser(Div):
""" """
return super().create( return super().create(
cond( cond(
~State.is_hydrated | has_connection_errors, # type: ignore has_connection_errors,
WifiOffPulse.create(**props), WifiOffPulse.create(**props),
), ),
position="fixed", position="fixed",

View File

@ -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.layout import Flex
from reflex.components.radix.themes.typography.text import Text from reflex.components.radix.themes.typography.text import Text
from reflex.constants import Dirs, Hooks, Imports from reflex.constants import Dirs, Hooks, Imports
from reflex.state import State
from reflex.utils import imports from reflex.utils import imports
from reflex.vars import Var, VarData from reflex.vars import Var, VarData

View File

@ -1835,11 +1835,9 @@ class OnLoadInternalState(State):
# Do not app.compile_()! It should be already compiled by now. # Do not app.compile_()! It should be already compiled by now.
app = getattr(prerequisites.get_app(), constants.CompileVars.APP) app = getattr(prerequisites.get_app(), constants.CompileVars.APP)
load_events = app.get_load_events(self.router.page.path) 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: if not load_events:
self.is_hydrated = True 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 self.is_hydrated = False
return [ return [
*fix_events( *fix_events(