feat: Added two more options to setvar.
Either provide a dot-separated string to access fields on objects or use a var to describe which value to set.
This enables you to write something like this:
import reflex as rx
class Object(rx.Base):
name: str = "1234"
class State(rx.State):
message: str = "Default"
object: Object = Object()
def index() -> rx.Component:
return rx.container(
rx.text(f"Object name: ", State.object.name),
rx.input(value=State.object.name, on_change=State.setvar(State.object.name)), # new syntax
rx.input(value=State.object.name, on_change=State.setvar("object.name")), #new syntax
rx.text(f"Message: ", State.message),
rx.input(value=State.message, on_change=State.setvar(State.message)), # new syntax
rx.input(value=State.message, on_change=State.setvar("message")),
)
app = rx.App()
app.add_page(index)
It might need some polishing with regard to nonexisting fields on objects, which is not checked for now. But I want to share a first version to get feedback.
use a var to describe which value to set
when i initially implemented setvar, this behavior was included, but a point was raised that it could introduce an incongruity and confusion.
consider the following code
rx.input(value=State.message, on_change=State.setvar(State.message))
it's not clear if i'm intending to set State.messages to the changed value, or if i'm trying to do indirection and set a var that is named the value of State.message to the changed value.
I still like "the State.a.set thing" https://github.com/reflex-dev/reflex/pull/3163#issuecomment-2083439794
But, as @masenf pointed out, we need descriptor based vars and event handlers for this to pass type checkers.
we need descriptor based vars and event handlers for this to pass type checkers
This is actually on the horizon. We're working on the Var refactor now and descriptor-based state Vars are part of that project.
OK, I see. Sorry that I didn't do the history digging :+1:
Thanks!
to be clear, i still think State.setvar("object.name") is sweet! we should keep that.
to be clear, i still think
State.setvar("object.name")is sweet! we should keep that.
Ah, sorry, tiny misunderstanding :smile: , so we are still in the game :game_die: . With your suggested change we can still write something like the following, which can help when refactoring, but typing is a bit :broken_heart:, but of course we can use a little # pyright: ignore[my-typing].
rx.input(
value=State.object.name, on_change=State.setvar(State.object.name._var_name)
)
@benedikt-bartscher Do you think this could still help then with our wild internal meta-programming dreams?
Or to help the confused API-users, we rename the function from setvar to apply_event_to or apply_value_to or apply_to and read this:
rx.input(value=State.message, on_click=State.apply_to(State.message))
Marking this as draft until resynced with main. Some of the recent addition for typing event handler might unblock this PR.
closing this due to inactivity, feels free to resurrect it when appropriate :+1:
closing this due to inactivity, feels free to resurrect it when appropriate π
Thanks for closing it for me. FMPOV it lost its charm when making it string-based again which is unstable under refactoring and not the best option when working with IDEs.