diff --git a/pynecone/app.py b/pynecone/app.py index 26b3e6d3f6..67efc530ac 100644 --- a/pynecone/app.py +++ b/pynecone/app.py @@ -11,7 +11,7 @@ from pynecone.compiler import compiler from pynecone.compiler import utils as compiler_utils from pynecone.components.component import Component, ComponentStyle -from pynecone.event import Event +from pynecone.event import Event, EventHandler from pynecone.middleware import HydrateMiddleware, Middleware from pynecone.model import Model from pynecone.state import DefaultState, Delta, State, StateManager, StateUpdate @@ -45,6 +45,9 @@ class App(Base): # Middleware to add to the app. middleware: List[Middleware] = [] + # events handlers to trigger when a page load + load_events: Dict[str, EventHandler] = {} + def __init__(self, *args, **kwargs): """Initialize the app. @@ -165,6 +168,7 @@ def add_page( title: str = constants.DEFAULT_TITLE, description: str = constants.DEFAULT_DESCRIPTION, image=constants.DEFAULT_IMAGE, + on_load: Optional[EventHandler] = None, ): """Add a page to the app. @@ -178,6 +182,7 @@ def add_page( title: The title of the page. description: The description of the page. image: The image to display on the page. + on_load: The event handler that will be called each time the page load. """ if path is not None: utils.deprecate( @@ -213,6 +218,9 @@ def add_page( self._check_routes_conflict(route) self.pages[route] = component + if on_load: + self.load_events[route] = on_load + def _check_routes_conflict(self, new_route: str): """Verify if there is any conflict between the new route and any existing route. diff --git a/pynecone/middleware/hydrate_middleware.py b/pynecone/middleware/hydrate_middleware.py index 9325c1c0d7..b5b405a73a 100644 --- a/pynecone/middleware/hydrate_middleware.py +++ b/pynecone/middleware/hydrate_middleware.py @@ -27,4 +27,13 @@ def preprocess(self, app: App, state: State, event: Event) -> Optional[Delta]: An optional state to return. """ if event.name == utils.get_hydrate_event(state): + route = event.router_data.get("pathname", "") + if route == "/": + load_event = app.load_events.get("index") + elif route: + load_event = app.load_events.get(route.lstrip("/")) + else: + load_event = None + if load_event: + load_event.fn(state) return utils.format_state({state.get_name(): state.dict()})