Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: PoC for shared states. #3679

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

abulvenz
Copy link
Contributor

@abulvenz abulvenz commented Jul 16, 2024

Fixes #2771 in a prototypical way.

Note class News(State, scope=State.topic): in example below.
What is working so far:
Open two tabs:

  • change "Title" to whatever and click "Post"
  • change "Title" in other tab and post.
  • See the entire state.

TODOs:

  • manage subscriptions to socket.io rooms based on scope vars
  • emit updates to socket.io rooms
  • make it work with redis
  • Initial subscriptions and state loading
  • redis pubsub
  • To use lists as scope, e.g. use case when subscribing to multiple channels at the same time, dynamic states of @benedikt-bartscher are needed [WIP] PoC Dynamic+global state #3671
import reflex as rx

app = rx.App()

class Article(rx.Base):
    title: str = "Title"
    content: str = "Content"

    def __str__(self):
        return f"{self.title}: {self.content}"

class State(rx.State):
    message: str = "Default"
    catalog: dict[str, str] = {"key": "value"}

    topic: str = "General"

    def printum(self):
        for key in app.state_manager.states.keys():
            print(key.split("_")[0])


class News(State, scope=State.topic):

    news: list[Article] = []

    def post(self, article: Article):
        print(f"Posting article {article}")
        self.news.append(article)


class NewNews(rx.State):
    draft: Article = Article()

    def set_title(self, title: str):
        self.draft.title = title

    def set_content(self, content: str):
        self.draft.content = content

def render_news(article: Article) -> rx.Component:
    return rx.box(
        rx.heading(article.title),
        rx.text(article.content),
    )

def index() -> rx.Component:
    return rx.container(
        rx.input(value=State.topic, on_change=State.setvar("topic")),
        rx.foreach(News.news, render_news),
        rx.input(value=NewNews.draft.title, on_change=NewNews.set_title),
        rx.input(value=NewNews.draft.content, on_change=NewNews.set_content),
        rx.button("Post", on_click=lambda :News.post(NewNews.draft)),
        rx.button("Printum", on_click=State.printum),
    )

app.add_page(index)

@abulvenz abulvenz marked this pull request as draft July 16, 2024 20:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature Request: Shared/Scoped State
1 participant