diff --git a/reflex/state.py b/reflex/state.py index c16b37b69c..6af70db14f 100644 --- a/reflex/state.py +++ b/reflex/state.py @@ -30,6 +30,7 @@ Type, Union, cast, + get_type_hints, ) import dill @@ -573,6 +574,15 @@ def __init_subclass__(cls, mixin: bool = False, **kwargs): for name, value in cls.__dict__.items() if types.is_backend_base_variable(name, cls) } + # Add annotated backend vars that do not have a default value. + new_backend_vars.update( + { + name: Var("", _var_type=annotation_value).get_default_value() + for name, annotation_value in get_type_hints(cls).items() + if name not in new_backend_vars + and types.is_backend_base_variable(name, cls) + } + ) cls.backend_vars = { **cls.inherited_backend_vars, diff --git a/tests/units/test_state.py b/tests/units/test_state.py index 89aad15364..205162b9f2 100644 --- a/tests/units/test_state.py +++ b/tests/units/test_state.py @@ -3216,6 +3216,7 @@ class MixinState(State, mixin=True): num: int = 0 _backend: int = 0 + _backend_no_default: dict @rx.var(cache=True) def computed(self) -> str: @@ -3243,11 +3244,16 @@ def test_mixin_state() -> None: """Test that a mixin state works correctly.""" assert "num" in UsesMixinState.base_vars assert "num" in UsesMixinState.vars - assert UsesMixinState.backend_vars == {"_backend": 0} + assert UsesMixinState.backend_vars == {"_backend": 0, "_backend_no_default": {}} assert "computed" in UsesMixinState.computed_vars assert "computed" in UsesMixinState.vars + assert ( + UsesMixinState(_reflex_internal_init=True)._backend_no_default # type: ignore + is not UsesMixinState.backend_vars["_backend_no_default"] + ) + def test_child_mixin_state() -> None: """Test that mixin vars are only applied to the highest state in the hierarchy."""