How to implement stateful, reusable components? #2592
-
Hello, I'm trying to implement a generic modal component that can be specialized for different use cases. The modal component knows how to show/hide, has a close button and can display error messages. Individual components can contain forms, ask to confirm actions etc. I was thinking to define a class ModalState(rx.State):
is_visible: bool = False
def _show(self):
if self.is_visible:
return
self.is_visible = True
self._on_show()
def _hide(self):
if not self.is_visible:
return
self.is_visible = False
chained_event = self._on_hide()
return chained_event
def _on_show(self):
pass
def _on_hide(self):
pass
def modal(header: str, state: type(ModalState)):
def decorator(rx_component_generator):
def wrapper():
return rx.box(
rx.modal(
rx.modal_overlay(
rx.modal_content(
rx.modal_header(header),
rx.modal_body(
rx_component_generator()
),
rx.modal_footer(
rx.button(
"Close",
on_click=state.hide
)
),
)
),
is_open=state.is_visible,
),
)
return wrapper
return decorator
class CreateAllocationState(modal.ModalState):
...
@modal.modal(
header="Create a new user",
state=CreateUserState)
def create_user_modal() -> rx.Component:
return rx.form(...)
The problem I'm facing is that -in my understanding- the same Is such use case supported? What is the recommended way to implement components that can reuse front-end as well as state logic? Thank you! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 3 replies
-
This is a possible use case, but reflex currently does not support it very well. A potential option is to have |
Beta Was this translation helpful? Give feedback.
-
Thank you for the great suggestion. I was using mixins as a workaround, to at least reuse behavior, but I'll definitely try this approach. Let me leave one more bit of info if someone else is attempting to do the same. (Presumably) due to the way handlers are referenced by class ModalState(rx.State):
def show(self):
... # generic modal logic here
self._on_show()
def _on_show(self): #hook for custom logic in the subclasses
pass
class CreateUserState(ModalState):
def _on_show(self):
print("hook for custom logic")
def myComponent() -> rx.Component:
...
rx.button("click",
on_click=CreateUserState.show) I would expect that clicking on the As a workaround, I explicitly implement |
Beta Was this translation helpful? Give feedback.
-
I also meant to link this earlier #1877 |
Beta Was this translation helpful? Give feedback.
This is a possible use case, but reflex currently does not support it very well.
A potential option is to have
is_visible
as a dict mapping some id to the bool value. Then each modal created by the decorator can generate anid
and use it to index into the dict (and event handlers) to control the state for that particular modal.