diff --git a/reflex/components/core/foreach.py b/reflex/components/core/foreach.py index 88f2886a8a6..9a6765491d2 100644 --- a/reflex/components/core/foreach.py +++ b/reflex/components/core/foreach.py @@ -8,6 +8,7 @@ from reflex.components.component import Component from reflex.components.tags import IterTag from reflex.constants import MemoizationMode +from reflex.state import ComponentState from reflex.utils import console from reflex.vars import Var @@ -50,6 +51,7 @@ def create( Raises: ForeachVarError: If the iterable is of type Any. + TypeError: If the render function is a ComponentState. """ if props: console.deprecate( @@ -65,6 +67,15 @@ def create( "(If you are trying to foreach over a state var, add a type annotation to the var). " "See https://reflex.dev/docs/library/layout/foreach/" ) + + if ( + hasattr(render_fn, "__qualname__") + and render_fn.__qualname__ == ComponentState.create.__qualname__ + ): + raise TypeError( + "Using a ComponentState as `render_fn` inside `rx.foreach` is not supported yet." + ) + component = cls( iterable=iterable, render_fn=render_fn, diff --git a/tests/components/core/test_foreach.py b/tests/components/core/test_foreach.py index 9691ed50e6f..6c418459031 100644 --- a/tests/components/core/test_foreach.py +++ b/tests/components/core/test_foreach.py @@ -3,8 +3,9 @@ import pytest from reflex.components import box, el, foreach, text +from reflex.components.component import Component from reflex.components.core.foreach import Foreach, ForeachRenderError, ForeachVarError -from reflex.state import BaseState +from reflex.state import BaseState, ComponentState from reflex.vars import Var @@ -37,6 +38,25 @@ class ForEachState(BaseState): color_index_tuple: Tuple[int, str] = (0, "red") +class TestComponentState(ComponentState): + """A test component state.""" + + foo: bool + + @classmethod + def get_component(cls, *children, **props) -> Component: + """Get the component. + + Args: + children: The children components. + props: The component props. + + Returns: + The component. + """ + return el.div(*children, **props) + + def display_color(color): assert color._var_type == str return box(text(color)) @@ -252,3 +272,12 @@ def test_foreach_component_styles(): ) component._add_style_recursive({box: {"color": "red"}}) assert 'css={{"color": "red"}}' in str(component) + + +def test_foreach_component_state(): + """Test that using a component state to render in the foreach raises an error.""" + with pytest.raises(TypeError): + Foreach.create( + ForEachState.colors_list, + TestComponentState.create, + )