From 94c9e524741b6257cc38ffe507c95e596cc398a7 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Thu, 16 Jan 2025 15:16:48 -0800 Subject: [PATCH] fix convert to component logic --- reflex/compiler/compiler.py | 34 +++++++++++++++++++++++++--------- reflex/state.py | 10 ++-------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/reflex/compiler/compiler.py b/reflex/compiler/compiler.py index c2f5662f4..54fb8b2f6 100644 --- a/reflex/compiler/compiler.py +++ b/reflex/compiler/compiler.py @@ -4,7 +4,7 @@ from __future__ import annotations from datetime import datetime from pathlib import Path -from typing import TYPE_CHECKING, Dict, Iterable, Optional, Tuple, Type, Union +from typing import TYPE_CHECKING, Callable, Dict, Iterable, Optional, Tuple, Type, Union from reflex import constants from reflex.compiler import templates, utils @@ -538,6 +538,29 @@ def purge_web_pages_dir(): if TYPE_CHECKING: from reflex.app import UnevaluatedPage + COMPONENT_TYPE = Union[Component, Var, Tuple[Union[Component, Var], ...]] + COMPONENT_TYPE_OR_CALLABLE = Union[COMPONENT_TYPE, Callable[[], COMPONENT_TYPE]] + + +def componentify_unevaluated( + possible_component: COMPONENT_TYPE_OR_CALLABLE, +) -> Component: + """Convert a possible component to a component. + + Args: + possible_component: The possible component to convert. + + Returns: + The component. + """ + if isinstance(possible_component, Var): + return Fragment.create(possible_component) + if isinstance(possible_component, tuple): + return Fragment.create(*possible_component) + if isinstance(possible_component, Component): + return possible_component + return componentify_unevaluated(possible_component()) + def compile_unevaluated_page( route: str, @@ -559,14 +582,7 @@ def compile_unevaluated_page( The compiled component and whether state should be enabled. """ # Generate the component if it is a callable. - component = page.component - - if isinstance(component, Var): - component = Fragment.create(component) - elif isinstance(component, tuple): - component = Fragment.create(*component) - elif not isinstance(component, Component): - component = component() + component = componentify_unevaluated(page.component) component._add_style_recursive(style or {}, theme) diff --git a/reflex/state.py b/reflex/state.py index 40b6dabf5..f9931f920 100644 --- a/reflex/state.py +++ b/reflex/state.py @@ -2554,8 +2554,7 @@ class ComponentState(State, mixin=True): Returns: A new instance of the Component with an independent copy of the State. """ - from reflex.components import Component - from reflex.components.base.fragment import Fragment + from reflex.compiler.compiler import componentify_unevaluated cls._per_component_state_instance_count += 1 state_cls_name = f"{cls.__name__}_n{cls._per_component_state_instance_count}" @@ -2568,12 +2567,7 @@ class ComponentState(State, mixin=True): # Save a reference to the dynamic state for pickle/unpickle. setattr(reflex.istate.dynamic, state_cls_name, component_state) component = component_state.get_component(*children, **props) - if isinstance(component, Var): - component = Fragment.create(component) - elif isinstance(component, tuple): - component = Fragment.create(*component) - elif not isinstance(component, Component): - component = component() + component = componentify_unevaluated(component) component.State = component_state return component