reflex
reflex copied to clipboard
feat: PoC for shared states.
Fixes https://github.com/reflex-dev/reflex/issues/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:
- [X] manage subscriptions to socket.io rooms based on scope vars
- [X] emit updates to socket.io rooms
- [X] 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 https://github.com/reflex-dev/reflex/pull/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)