-
Notifications
You must be signed in to change notification settings - Fork 364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uncontrolled input if :onChange
is specified
#295
Comments
Please excuse my lack of knowledge, but isn't that because you're using render instead of render-state? |
@JulianLeviston Sorry, I don't see what Render vs. RenderState has to do with this. Could you explain what you mean? @swannodette Looking at the source it seems that this behaviour is intentional. What is the rationale for this? It means that you can't do standard React things like (dom/input #js {:type "text" :value (:text app)
:onChange #(let [new-value (-> % .-target .-value)]
(when (< (count (:text app)) 10)
(om/transact! app :text (fn [old-value]
new-value))))}) |
Apologies. I shouldn't have commented. I clearly don't understand the problem. |
@jonase the patching of form elements is necessary to avoid issues that arise out of async rendering. Better solution ideas welcome. |
@swannodette Thanks! I would like to understand this problem more deeply.
|
No flag for disabling async rendering. Use React DOM elements directly if you want to observe the issues. In particular text inputs behave badly. |
@swannodette After some searching I found facebook/react#1759 where the issue with controlled components and rAF is discussed. I also found this statement from one of the React developers[1]
so it seems that making rAF work seamlessly with the React model is currently not a priority. [1] https://groups.google.com/d/msg/reactjs/LkTihnf6Ey8/FgFvvf33GckJ |
I played around with this some more and I found that even with the current implementation, the following (def app-state (atom {:text "foo"}))
(defn my-input [app]
(reify
om/IRender
(render [this]
(dom/input
#js {:type "text"
:value (.toUpperCase (:text app))
:onChange #(om/transact! app
:text
(constantly (-> % .-target .-value)))}))))
(om/root
my-input
app-state
{:target (. js/document (getElementById "app"))}) will cause the cursor to jump to the last position and this seems to be one of the symptoms of async rendering. Note that if I replace Even more interesting is the fact that, even thou the implementation is completely different, Reagent behaves in exactly the same way as Om in this case: (defn my-input [on-change text]
[:div [:input {:type "text"
:value (.toUpperCase text)
:on-change #(on-change (-> % .-target .-value))}]])
(def text (reagent/atom "foo"))
(defn main-page []
[my-input #(reset! text %) @text]) Here also, the cursor will jump to the last position and if I replace |
Sorry I've been a bit busy with cljs.test and test.check work. In order to get controlled input behavior you must:
That is, the contract of This is implicit in the tutorial but perhaps could be better documented as a hard requirement until a better solution is provided for. |
This is not something that needs fixing. |
If an input uses the
:onChange
callback it is uncontrolled even if:value
is specified. Here's a small reproducible test:In React all three inputs are controlled (http://jsfiddle.net/69z2wepo/220/)
The text was updated successfully, but these errors were encountered: