Skip to content

Commit 69ca396

Browse files
authored
do not add auto setters on reflex states (#5314)
* do not add auto setters on reflex states * fix call script and input * enable auto setters * fix the tests by not changing the payload to set_is_hydrated * darglint, dang it * handle the dynamic case
1 parent 0c1f2fb commit 69ca396

File tree

4 files changed

+54
-5
lines changed

4 files changed

+54
-5
lines changed

reflex/state.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,18 @@ def get_class_var(cls, path: Sequence[str]) -> Any:
10031003
raise ValueError(f"Invalid path: {path}")
10041004
return getattr(substate, name)
10051005

1006+
@classmethod
1007+
def is_user_defined(cls) -> bool:
1008+
"""Check if the state is user-defined.
1009+
1010+
Returns:
1011+
True if the state is user-defined, False otherwise.
1012+
"""
1013+
return (
1014+
not cls.__module__.startswith("reflex.")
1015+
or cls.__module__ == "reflex.istate.dynamic"
1016+
)
1017+
10061018
@classmethod
10071019
def _init_var(cls, prop: Var):
10081020
"""Initialize a variable.
@@ -1024,7 +1036,7 @@ def _init_var(cls, prop: Var):
10241036
f'Found var "{prop._js_expr}" with type {prop._var_type}.'
10251037
)
10261038
cls._set_var(prop)
1027-
if get_config().state_auto_setters:
1039+
if cls.is_user_defined() and get_config().state_auto_setters:
10281040
cls._create_setter(prop)
10291041
cls._set_default_value(prop)
10301042

@@ -2330,6 +2342,15 @@ class State(BaseState):
23302342
# The hydrated bool.
23312343
is_hydrated: bool = False
23322344

2345+
@event
2346+
def set_is_hydrated(self, value: bool) -> None:
2347+
"""Set the hydrated state.
2348+
2349+
Args:
2350+
value: The hydrated state.
2351+
"""
2352+
self.is_hydrated = value
2353+
23332354

23342355
T = TypeVar("T", bound=BaseState)
23352356

@@ -2424,7 +2445,7 @@ class OnLoadInternalState(State):
24242445
This is a separate substate to avoid deserializing the entire state tree for every page navigation.
24252446
"""
24262447

2427-
def on_load_internal(self) -> list[Event | EventSpec] | None:
2448+
def on_load_internal(self) -> list[Event | EventSpec | event.EventCallback] | None:
24282449
"""Queue on_load handlers for the current page.
24292450
24302451
Returns:
@@ -2444,7 +2465,7 @@ def on_load_internal(self) -> list[Event | EventSpec] | None:
24442465
self.router.session.client_token,
24452466
router_data=self.router_data,
24462467
),
2447-
State.set_is_hydrated(True), # pyright: ignore [reportAttributeAccessIssue]
2468+
State.set_is_hydrated(True),
24482469
]
24492470

24502471

tests/integration/test_call_script.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,22 @@ def call_with_var_str_cast_wrapped(self):
182182
callback=CallScriptState.setvar("last_result"),
183183
)
184184

185+
@rx.event
186+
def set_inline_counter(self, value: str):
187+
self.inline_counter = int(value)
188+
189+
@rx.event
190+
def set_external_counter(self, value: str):
191+
self.external_counter = int(value)
192+
193+
@rx.event
194+
def set_last_result(self, value: str):
195+
self.last_result = int(value)
196+
197+
@rx.event
198+
def set_value(self, value: str):
199+
self.value = value
200+
185201
@rx.event
186202
def reset_(self):
187203
yield rx.call_script("inline_counter = 0; external_counter = 0")

tests/integration/test_client_storage.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ class ClientSideState(rx.State):
3030
state_var: str = ""
3131
input_value: str = ""
3232

33+
@rx.event
34+
def set_state_var(self, value: str):
35+
self.state_var = value
36+
37+
@rx.event
38+
def set_input_value(self, value: str):
39+
self.input_value = value
40+
3341
class ClientSideSubState(ClientSideState):
3442
# cookies with default settings
3543
c1: str = rx.Cookie()

tests/integration/test_input.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ def FullyControlledInput():
1616
class State(rx.State):
1717
text: str = "initial"
1818

19+
@rx.event
20+
def set_text(self, text: str):
21+
self.text = text
22+
1923
app = rx.App()
2024

2125
@app.add_page
@@ -26,11 +30,11 @@ def index():
2630
),
2731
rx.input(
2832
id="debounce_input_input",
29-
on_change=State.set_text, # pyright: ignore [reportAttributeAccessIssue]
33+
on_change=State.set_text,
3034
value=State.text,
3135
),
3236
rx.input(value=State.text, id="value_input", is_read_only=True),
33-
rx.input(on_change=State.set_text, id="on_change_input"), # pyright: ignore [reportAttributeAccessIssue]
37+
rx.input(on_change=State.set_text, id="on_change_input"),
3438
rx.el.input(
3539
value=State.text,
3640
id="plain_value_input",

0 commit comments

Comments
 (0)