I’m using Material-UI + Reagent/Re-frame for a new project, and I’ve come across the problem of the controlled Material-UI TextField not working well with Reagent, as described in the Reagent docs.
I started using the suggested workaround, but wasn’t really happy about it not working with multiline text fields with a non-fixed number of rows.
Then it occurred to me that there’s an easier workaround, which is to just use an uncontrolled TextField with a ^{:key ...}
metadata attached. When I need to re-render the TextField (e.g. after fetching data from a database) then I can change the key to force a re-render.
;; A way to force an uncontrolled textfield to re-render is to change the key
(defonce !text (r/atom "Initial text in !text atom"))
(defonce !key (r/atom 1))
(defn uncontrolled-with-key []
[:form {:no-validate true
:auto-complete "off"}
^{:key @!key}
[:> TextField {:id "uncontrolled-textfield"
:multiline true
:variant "outlined"
:label "Uncontrolled"
:on-change #(reset! !text (-> % .-target .-value))
:default-value @!text}]])
(comment
; Run these snippets in the REPL
; Changing the text atom won't make the textfield re-render
(reset! !text "Some new text")
; But changing the key will
(swap! !key inc))
Is there any downside to doing things this way?