diff --git a/solara/toestand.py b/solara/toestand.py index af76efc8b..247bb68b3 100644 --- a/solara/toestand.py +++ b/solara/toestand.py @@ -496,9 +496,12 @@ def wrapper(f: Callable[[], T]): return wrapper(f) -class ReactiveField(ValueBase[T]): +class ReactiveField(Reactive[T]): def __init__(self, field: "FieldBase"): - super().__init__() # type: ignore + # super().__init__() # type: ignore + # We skip the Reactive constructor, because we do not need it, but we do + # want to be an instanceof for use in use_reactive + ValueBase.__init__(self) self._field = field field = field while not isinstance(field, ValueBase): @@ -558,6 +561,9 @@ def peek(self) -> T: def set(self, value: T): self._field.set(value) + def update(self, *args, **kwargs): + ValueBase.update(cast(ValueBase, self), *args, **kwargs) + def Ref(field: T) -> Reactive[T]: _field = cast(FieldBase, field) diff --git a/tests/unit/toestand_test.py b/tests/unit/toestand_test.py index ef4106a00..7ce17dfc1 100644 --- a/tests/unit/toestand_test.py +++ b/tests/unit/toestand_test.py @@ -462,7 +462,7 @@ def ThemeInfo(): @react.component def ThemeSelector(): theme, set_theme = Ref(settings.fields["theme"]).use_state() # type: ignore - with sol.ToggleButtonsSingle(theme, on_value=set_theme) as main: + with sol.ToggleButtonsSingle(theme, on_value=set_theme) as main: # type: ignore sol.Button("dark") sol.Button("light") return main @@ -1016,6 +1016,24 @@ def Test(): rc.close() +def test_use_reactive_ref(): + reactive_var = Reactive({"a": 1}) + reactive_ref = Ref(reactive_var.fields["a"]) + + reactive_ref_test: Reactive[int] = None + + @solara.component + def Test(): + nonlocal reactive_ref_test + reactive_ref_test = solara.use_reactive(reactive_ref) + return solara.IntSlider("test: " + str(reactive_ref.value), value=reactive_ref_test) + + box, rc = solara.render(Test(), handle_error=False) + assert reactive_ref_test is not None + assert reactive_ref_test.value == 1 + rc.close() + + def test_use_reactive_on_change(): control = Reactive(0) var1 = Reactive(1)