1919 EventQueueEntry ,
2020 RegisteredEventHandler ,
2121)
22+ from reflex_core .utils .format import format_event_handler
2223
2324if TYPE_CHECKING :
2425 from reflex .event import EventHandler , EventSpec
2526 from reflex .state import BaseState
2627
2728
29+ @functools .lru_cache (maxsize = 1 )
30+ def _hydrate_event_name ():
31+ from reflex .state import State
32+
33+ return format_event_handler (State .event_handlers ["hydrate" ])
34+
35+
2836def _check_valid_yield (events : Any , handler_name : str = "unknown" ) -> Any :
2937 """Check if the events yielded are valid. They must be EventHandlers or EventSpecs.
3038
@@ -271,6 +279,33 @@ class BaseStateEventProcessor(EventProcessor):
271279 frontend.
272280 """
273281
282+ async def _rehydrate (self , root_state : BaseState ):
283+ """Rehydrate the state by calling the hydrate event handler.
284+
285+ Args:
286+ root_state: The root state to rehydrate.
287+ """
288+ from reflex .state import OnLoadInternalState , State
289+
290+ if (
291+ type (root_state ) is not State
292+ or OnLoadInternalState .get_name () not in root_state .substates
293+ ):
294+ return
295+
296+ await process_event (
297+ handler = State .event_handlers ["hydrate" ],
298+ payload = {},
299+ state = root_state ,
300+ root_state = root_state ,
301+ )
302+ await process_event (
303+ handler = OnLoadInternalState .event_handlers ["on_load_internal" ],
304+ payload = {},
305+ state = await root_state .get_state (OnLoadInternalState ),
306+ root_state = root_state ,
307+ )
308+
274309 async def _process_event_queue_entry (
275310 self , * , entry : EventQueueEntry , registered_handler : RegisteredEventHandler
276311 ) -> None :
@@ -295,7 +330,10 @@ async def _process_event_queue_entry(
295330 ),
296331 event = entry .event ,
297332 ) as state :
298- # TODO: handle "reload" trigger of brand new state instances
333+ # Compatibility hack rehydrate the state before processing this event.
334+ needs_to_rehydrate = bool (
335+ not state .router_data and event .name != _hydrate_event_name ()
336+ )
299337
300338 # re-assign only when the value is set and different
301339 if router_data and state .router_data != router_data :
@@ -322,6 +360,9 @@ async def _process_event_queue_entry(
322360 substate = await state .get_state (event .state_cls )
323361 root_state = state ._get_root_state ()
324362
363+ if needs_to_rehydrate :
364+ await self ._rehydrate (root_state )
365+
325366 # Process non-background events while holding the lock.
326367 if not registered_handler .handler .is_background :
327368 await process_event (
0 commit comments