`rx.input(value=State.nested.var)` is not updated when `nested` is set to a new object containing the same content.
Describe the bug We have some validation checks in setters that do not let through some changes from the frontend. Unfortunately the reload button does not reset the UI.
To Reproduce Steps to reproduce the behavior:
- Use below app
- Type an "a" into the input
- Because your input is invalid, the state is not updated in the setter.
- Click "Create new Object". This will overwrite the object in the state. # Here I would expect an update in the input.
- The input still shows the old value, containing the "a".
- Click "Create other Object". This time the input changes to "12345"
import reflex as rx
class Object(rx.Base):
name: str = "1234"
class State(rx.State):
"""The app state."""
message: str = "Default"
object: Object = Object()
def create_new_object(self):
self.object = Object()
self.message = self.object.name
print(self.object.name)
def create_new_object_2(self):
self.object = Object(name="12345")
self.message = self.object.name
print(self.object.name)
def set_name(self, value: str):
if not "a" in value:
self.object.name = value
self.message = ""
else:
self.message="You can't use the letter 'a' in the name"
def index() -> rx.Component:
return rx.container(
rx.text(f"Your message: ", State.message),
rx.text(f"Object name: ", State.object.name),
rx.input(value=State.object.name, on_change=State.set_name),
rx.button("Create new object", on_click=State.create_new_object),
rx.button("Create other object", on_click=State.create_new_object_2),
)
app = rx.App()
app.add_page(index)
Expected behavior The input should show the variable value after pressing the button.
I believe the issue is https://github.com/nkbt/react-debounce-input/issues/130
The internal state of the debounce is not getting updated because the bound state var does not actually change value [1].
I'm not sure if there's actually a fix we can make here π, but there are some potential workarounds:
- set
keyprop on therx.inputto some value in the state that you increment/update when the object updates. This will force the input to be re-rendered with the correct value showing... Note however, reflex 0.5.6 currently has a bug wherekeyis not passed through, so this would also need to be fixed in the framework before it's a real solution - trigger a state update in
self.object.nameto a different value, then set it back to the original value in theset_namefunction. The problem here is that the user gets their input swiped out from under them and reset to the last "valid" value, which is not a great UX. - in the
create_new_objecthandler, if the new object name matches the current object name, firstyielda state update that blanks out theself.object.namefield, then updateself.objectto the new object. This is probably the cleanest workaround, but if these objects are getting created and assigned in multiple places, it's kind of a hassle, so you might need a helper function to handle the logic.
Thanks for the fast reply @masenf .
We have implemented the last workaround and yield the entire object as None and yield the new value afterwards. It causes a tiny flicker depending on the state size, but at least it works now as expected.
We could try https://github.com/xnimorz/use-debounce which seems to be better maintained