reflex/reflex/components/core/client_side_routing.py
Thomas Brandého b8b3f8910e
add more type annotations through the code (#4401)
* add more type annotations through the code

* add typing in reflex/utils

* misc typing

* more typings

* state typing

* keep typing

* typing init and utils

* more typing for components

* fix attempt for 3.9

* need more __future

* more typings

* type event plz

* type model

* type vars/base.py

* enable 'ANN001' for reflex folder (ignore tests and benchmarks)

* fix pyi

* add missing annotations

* use more precise error when ignoring
2025-01-29 01:12:47 +01:00

70 lines
1.9 KiB
Python

"""Handle dynamic routes in static exports via client-side routing.
Works with /utils/client_side_routing.js to handle the redirect and state.
When the user hits a 404 accessing a route, redirect them to the same page,
setting a reactive state var "routeNotFound" to true if the redirect fails. The
`wait_for_client_redirect` function will render the component only after
routeNotFound becomes true.
"""
from __future__ import annotations
from reflex import constants
from reflex.components.component import Component
from reflex.components.core.cond import cond
from reflex.vars.base import Var
route_not_found: Var = Var(_js_expr=constants.ROUTE_NOT_FOUND)
class ClientSideRouting(Component):
"""The client-side routing component."""
library = "$/utils/client_side_routing"
tag = "useClientSideRouting"
def add_hooks(self) -> list[str | Var]:
"""Get the hooks to render.
Returns:
The useClientSideRouting hook.
"""
return [f"const {constants.ROUTE_NOT_FOUND} = {self.tag}()"]
def render(self) -> str:
"""Render the component.
Returns:
Empty string, because this component is only used for its hooks.
"""
return ""
def wait_for_client_redirect(component: Component) -> Component:
"""Wait for a redirect to occur before rendering a component.
This prevents the 404 page from flashing while the redirect is happening.
Args:
component: The component to render after the redirect.
Returns:
The conditionally rendered component.
"""
return cond(
condition=route_not_found,
c1=component,
c2=ClientSideRouting.create(),
)
class Default404Page(Component):
"""The NextJS default 404 page."""
library = "next/error"
tag = "Error"
is_default = True
status_code: Var[int] = Var.create(404)