[REF-2158] Enable state when on_load
or event_triggers are set. (#2815)
* [REF-2158] Enable state when `on_load` or event_triggers are set. Basically all events in a reflex app require the backend to be up, even the built-in server side events round trip to the backend and require "state" even if no user-defined state classes are declared. test_app_state_determination: checking that state is enabled at the right time * Clear out DECORATED_PAGES when initializing a new app
This commit is contained in:
parent
bf297e2f5b
commit
c809107d09
@ -453,14 +453,18 @@ class App(Base):
|
|||||||
# Generate the component if it is a callable.
|
# Generate the component if it is a callable.
|
||||||
component = self._generate_component(component)
|
component = self._generate_component(component)
|
||||||
|
|
||||||
|
# Ensure state is enabled if this page uses state.
|
||||||
if self.state is None:
|
if self.state is None:
|
||||||
for var in component._get_vars(include_children=True):
|
if on_load or component._has_event_triggers():
|
||||||
if not var._var_data:
|
|
||||||
continue
|
|
||||||
if not var._var_data.state:
|
|
||||||
continue
|
|
||||||
self.enable_state()
|
self.enable_state()
|
||||||
break
|
else:
|
||||||
|
for var in component._get_vars(include_children=True):
|
||||||
|
if not var._var_data:
|
||||||
|
continue
|
||||||
|
if not var._var_data.state:
|
||||||
|
continue
|
||||||
|
self.enable_state()
|
||||||
|
break
|
||||||
|
|
||||||
component = OverlayFragment.create(component)
|
component = OverlayFragment.create(component)
|
||||||
|
|
||||||
|
@ -873,6 +873,20 @@ class Component(BaseComponent, ABC):
|
|||||||
|
|
||||||
return vars
|
return vars
|
||||||
|
|
||||||
|
def _has_event_triggers(self) -> bool:
|
||||||
|
"""Check if the component or children have any event triggers.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if the component or children have any event triggers.
|
||||||
|
"""
|
||||||
|
if self.event_triggers:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
for child in self.children:
|
||||||
|
if isinstance(child, Component) and child._has_event_triggers():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def _get_custom_code(self) -> str | None:
|
def _get_custom_code(self) -> str | None:
|
||||||
"""Get custom code for the component.
|
"""Get custom code for the component.
|
||||||
|
|
||||||
|
@ -225,6 +225,8 @@ class AppHarness:
|
|||||||
with chdir(self.app_path):
|
with chdir(self.app_path):
|
||||||
# ensure config and app are reloaded when testing different app
|
# ensure config and app are reloaded when testing different app
|
||||||
reflex.config.get_config(reload=True)
|
reflex.config.get_config(reload=True)
|
||||||
|
# Clean out any `rx.page` decorators from other tests.
|
||||||
|
reflex.app.DECORATED_PAGES.clear()
|
||||||
# reset rx.State subclasses
|
# reset rx.State subclasses
|
||||||
State.class_subclasses.clear()
|
State.class_subclasses.clear()
|
||||||
State.class_subclasses.update(INTERNAL_STATES)
|
State.class_subclasses.update(INTERNAL_STATES)
|
||||||
|
@ -1319,3 +1319,38 @@ def test_app_wrap_priority(compilable_app):
|
|||||||
")"
|
")"
|
||||||
"}"
|
"}"
|
||||||
) in "".join(app_js_lines)
|
) in "".join(app_js_lines)
|
||||||
|
|
||||||
|
|
||||||
|
def test_app_state_determination():
|
||||||
|
"""Test that the stateless status of an app is determined correctly."""
|
||||||
|
a1 = App()
|
||||||
|
assert a1.state is None
|
||||||
|
|
||||||
|
# No state, no router, no event handlers.
|
||||||
|
a1.add_page(rx.box("Index"), route="/")
|
||||||
|
assert a1.state is None
|
||||||
|
|
||||||
|
# Add a page with `on_load` enables state.
|
||||||
|
a1.add_page(rx.box("About"), route="/about", on_load=rx.console_log(""))
|
||||||
|
assert a1.state is not None
|
||||||
|
|
||||||
|
a2 = App()
|
||||||
|
assert a2.state is None
|
||||||
|
|
||||||
|
# Referencing a state Var enables state.
|
||||||
|
a2.add_page(rx.box(rx.text(GenState.value)), route="/")
|
||||||
|
assert a2.state is not None
|
||||||
|
|
||||||
|
a3 = App()
|
||||||
|
assert a3.state is None
|
||||||
|
|
||||||
|
# Referencing router enables state.
|
||||||
|
a3.add_page(rx.box(rx.text(State.router.page.full_path)), route="/")
|
||||||
|
assert a3.state is not None
|
||||||
|
|
||||||
|
a4 = App()
|
||||||
|
assert a4.state is None
|
||||||
|
|
||||||
|
# Referencing an event handler enables state.
|
||||||
|
a4.add_page(rx.box(rx.button("Click", on_click=rx.console_log(""))), route="/")
|
||||||
|
assert a4.state is not None
|
||||||
|
Loading…
Reference in New Issue
Block a user