diff --git a/reflex/state.py b/reflex/state.py index 73ebc0892..86bb91d17 100644 --- a/reflex/state.py +++ b/reflex/state.py @@ -200,6 +200,7 @@ def _no_chain_background_task( RESERVED_BACKEND_VAR_NAMES = { + "_abc_impl", "_backend_vars", "_was_touched", } @@ -558,6 +559,14 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow): cls.computed_vars[newcv._var_name] = newcv cls.vars[newcv._var_name] = newcv continue + if ( + types.is_backend_variable(name, cls) + and name not in RESERVED_BACKEND_VAR_NAMES + and name not in cls.inherited_backend_vars + and not isinstance(value, FunctionType) + ): + cls.backend_vars[name] = copy.deepcopy(value) + continue if events.get(name) is not None: continue if not cls._item_is_event_handler(name, value): diff --git a/tests/test_state.py b/tests/test_state.py index 1974e6daa..b18fd259c 100644 --- a/tests/test_state.py +++ b/tests/test_state.py @@ -2969,3 +2969,23 @@ config = rx.Config( state_manager = StateManager.create(state=State) assert state_manager.lock_expiration == expected_values[0] # type: ignore assert state_manager.token_expiration == expected_values[1] # type: ignore + + +class MixinState(State, mixin=True): + """A mixin state for testing.""" + + num: int = 0 + _backend: int = 0 + + +class UsesMixinState(MixinState, State): + """A state that uses the mixin state.""" + + pass + + +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}