React: Controlled input allows dot

Created on 29 Apr 2017  路  10Comments  路  Source: facebook/react

Do you want to request a feature or report a bug?
bug

What is the current behavior?
React allows a dot in a controlled input that doesn't allow changing the value, if the value set as a prop is a number. If it's a string the issue is not present.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template: https://jsfiddle.net/84v837e9/).
https://jsfiddle.net/84v837e9/23/

In this example the first input allows a dot, even though the code doesn't allow changes. The second input doesn't allow the dot.

What is the expected behavior?
The dot shouldn't be allowed.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
version 15.5.4, Chrome and Firefox (see the jsfiddle example)

Bug

Most helpful comment

I sent out a PR here: https://github.com/facebook/react/pull/9584

Sorry for the trouble.

All 10 comments

This is interesting. The reason for this is because 2. or 2.0 (which is also allowed) equals to 2. Casting the value to a String first before doing the comparison could fix this problem, however it could be also intended behavior.

But note that the type of the input is "text" and such an input will always give you a string and "2." is by no means equal to either "2" or 2 (number). Also "2.000000000000" is very different from 2.

I'm not sure what you mean by casting the value to a String, since the input (with type "text") always gives you a string.

Think the actual problem is caused by this check value != node.value here https://github.com/facebook/react/blob/master/src/renderers/dom/stack/client/wrappers/ReactDOMInput.js#L205, which gets skipped because of value 2 equals "2.". When it gets changed to !== it does the trick.

Yes, value should be explicitly converted to string before comparing to node.value

I'm not sure what you mean by casting the value to a String, since the input (with type "text") always gives you a string.

This is about the value that you give via props, not the actual input value

@nhunzaker what was the reason for using loose equality checks for value with text inputs?

I believe this was a relic of dealing with edge cases on number inputs. In short: if we touch the value property of number inputs whatsoever, Chrome/Safari will do unexpected things like drop trailing decimal places, clear out invalid input, etc.

So this needs to go. When I added the condition to specifically check for the number type, I didn't remove this check. I'm wrapping up some text fixtures for it, and I should have something out for review later today.

I sent out a PR here: https://github.com/facebook/react/pull/9584

Sorry for the trouble.

9584 is merged now, issue can be closed 馃憤

Was this page helpful?
0 / 5 - 0 ratings