Do you want to request a feature or report a bug?
bug
What is the current behavior?
When you directly after the loading choose the maximum value on the input type range, the event isn't fire with an onChange. The event is fire when it's not the maximum value of the input.
Sandbox: https://codesandbox.io/s/7kv59yj360
Click on the maximum (right) of the input of type range.
There is no message on the console and the displayed value doesn't change as expected
Click on a other value on the input, a message is displayed in the console and the value change
When you click on the last value it's now displayed.
What is the expected behavior?
An event should trigger when you directly click on the maximum value of the input of type range.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
Testing on macOS High Sierra, Firefox 60.0.1, Safari 11.1, Chrome 66.0.3359.181, react 16.2.0
To get around this behaviour, I had to change onChange by onInput but add a blanck onChange to still get the drag behaviour on Safari on Iphone (see this CodeSandBox )
The workaround of using onInput instead of onChange works well but React thinks that the field is uncontrolled and shows a warning.
Without React, there is no issue with the onChange listener on a range input.
https://jsfiddle.net/L0L07119/
@brainlulz I found one interesting thing, the range work after I remove your max attribute, see
https://codesandbox.io/s/318jw3jjkq
It may be related to how react set the attributes when rendering the dom
It looks like this only happens when max is equal or less than 50.
@whs-dot-hk That's why by removing the max attribute, the range works because max defaults to 100
The value of range is not a integer as everyone expected, it is a string
https://codesandbox.io/s/ykkon3qp5j (Edited)
same here
It doesn't change anything to the issue described here.
https://codesandbox.io/s/r883k20pn
When you use html native properties it is string anyway
<input type="range" max="10" />
Compare
https://codesandbox.io/s/81m5w3q4ql
with
https://codesandbox.io/s/llx9714o7m
both of them fire the event input when click on the max value, the max=60 one fire input then change event, but max=10
Is changing the code binding the default of onInput to onChange possible here? Is there any drawbacks?
This sounds like something that should be easy to fix. Anyone wants to look into why this is happening?
@gaearon I'm currently working on it
Sorry, I should have explained what's happening here when I marked it as a bug.
The reason this is happening is because range inputs will have a default value.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/range
The default value is halfway between the specified minimum and maximum鈥攗nless the maximum is actually less than the minimum, in which case the default is set to the value of the min attribute.
When we track the input's value we read that value property, initializing the tracked value to to the default. In this case, it defaults to 10 because of the order in which the properties are assigned.
value defaults to 50min attribute is set, value stays at 50max attribute is set, value is changed to 10 since 50 is greater than the new maxWhen we track the input's value we define a getter/setter for the value attribute, which _should_ correct the tracked value the next time it's updated. But since the current value _isn't_ empty, we skip setting value and only set defaultValue, which doesn't update the tracked value. So when you go to update the input by setting it to the max, it doesn't actually update because it thinks the tracked value is _already_ the max.
A couple solutions would be:
postMountWrapper that checks if the element is a range input.inputValueTracking so it updates the tracked value when defaultValue is set as wellThe first option is likely the easiest solution. I'm not sure what effects updating inputValueTracking might have, we could be relying on the tracked value and the defaultValue to be different in some cases.
@Illu I have a fix locally I can submit, but if you want to give it a try feel free to and I'll defer to you 馃檪
@aweary thanks man ! I'll give it a try 馃槂
@aweary May I present you some test case
I have wrote mine, but this is already there
It said the order
Some test case I wrote
https://github.com/whs-dot-hk/react/commit/5dc4073b4e9b4440754ee3234ea7dfc0a4762911
It's the value always correct? Or is it 50?
Fixed in React 16.4.1.
oninput working perfect instant of onchange
Most helpful comment
Sorry, I should have explained what's happening here when I marked it as a bug.
The reason this is happening is because
rangeinputs will have a defaultvalue.https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/range
When we track the input's value we read that
valueproperty, initializing the tracked value to to the default. In this case, it defaults to10because of the order in which the properties are assigned.valuedefaults to50minattribute is set,valuestays at50maxattribute is set,valueis changed to10since50is greater than the new maxWhen we track the input's value we define a getter/setter for the
valueattribute, which _should_ correct the tracked value the next time it's updated. But since the current value _isn't_ empty, we skip settingvalueand only setdefaultValue, which doesn't update the tracked value. So when you go to update the input by setting it to the max, it doesn't actually update because it thinks the tracked value is _already_ the max.A couple solutions would be:
postMountWrapperthat checks if the element is a range input.inputValueTrackingso it updates the tracked value whendefaultValueis set as wellThe first option is likely the easiest solution. I'm not sure what effects updating
inputValueTrackingmight have, we could be relying on the tracked value and the defaultValue to be different in some cases.