reflex-dev / reflex

🕸️ Web apps in pure Python 🐍
https://reflex.dev
Apache License 2.0
19.86k stars 1.14k forks source link

List of ComponentState as Frontend Var Breaks #4188

Open sebastianjanisch opened 1 week ago

sebastianjanisch commented 1 week ago

Describe the bug When using ComponentState instances inside front-end variables for dynamic rendering of components, exceptions are raised.

To Reproduce Steps to reproduce the behavior:

import asyncio
import reflex as rx

class MessageComponent(rx.ComponentState):

    message: str = ""

    @classmethod
    def get_component(cls, size: str) -> rx.Component:
        return rx.flex(
            rx.text(f"My text: {cls.message}", size=size),
            rx.markdown(f"*My markdown*: {cls.message}", size=size),
        )

message_component = MessageComponent.create

class BugState(rx.State):

    _messages: list[MessageComponent] = []

    @rx.var()
    def messages(self) -> rx.Component:
        return rx.vstack(
            *[m for m in self._messages]
        )

    async def add_message(self):
        self._messages.append(message_component(size="3"))

        for e in "This is a test message!".split():
            self._messages[-1].State.message += e
            yield
            await asyncio.sleep(0.1)

@rx.page(route="/test")
def bug() -> rx.Component:
    return rx.vstack(
        message_component(size="6"),
        BugState.messages,
        rx.button("Add Message", on_click=BugState.add_message),
        width="100%",
    )

Expected behavior I should be able to add different ComponentState instances to a backend list var and then render them through a front end variable. The broader context is to create different UI components based on dynamic criteria.

Screenshots If applicable, add screenshots to help explain your problem.

Specifics (please complete the following information):

Additional context Add any other context about the problem here.

benedikt-bartscher commented 3 days ago

This requires "dynamic state" which is currently not implemented in reflex. Take a look here https://github.com/reflex-dev/reflex/issues/3718