Skip to content
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

For Controlled Input, step does not work as expected unless initialized with null or "". #12334

Open
andyboyne opened this issue Mar 6, 2018 · 7 comments

Comments

@andyboyne
Copy link

andyboyne commented Mar 6, 2018

BUG

What is the current behavior?
For input type="number", step does not work as expected if there is an initial value set. Step only seems to get honored if the initial value is "" or null.

Example:
https://codepen.io/anon/pen/MQMBmX

The example uses a controlled input binding value and step. Step is 1/10th of the value. If you edit the value in the textbox to 50000 and increment using the stepper, it will increment to 50100 (i.e. by the initial value and not by the current step).

Edit the code so initial value is "" or null. Edit textbox to 50000 and step up - value goes to 55000 as expected.

What is the expected behavior?
It should be possible to render a number input that honors step without having to initialize the input component value to null or "" first.

It seems when there is an initial value provided, it will write a value attribute into the DOM (e.g. value="100"). When initial value is "" or null then just the value attribute is written to DOM with no assignment. e.g. (value).

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

16.3.0-alpha.1 (ported to this version to confirm if still an issue)
0.14.7 (originally found in this version)

Seems to affect Chrome only (confirmed windows and mac, versions 59 and 64). Bug does not appear in Safari (on a mac at least).

@nmain
Copy link

nmain commented Mar 6, 2018

I'm seeing a very particular behavior with this fiddle in both Chrome 64 on Windows 10 and Firefox 52 on Debian. If I type 50000 into the input and then immediately click on the up arrow, I get 50100. If I type 50000 into the input, click elsewhere in the document, and then click on the up arrow, I get 55000.

@jmz7v
Copy link

jmz7v commented Mar 12, 2018

You don't need to change the value, click the up arrow multiple times and it starts to change to numbers that don't make sense.

@aweary
Copy link
Contributor

aweary commented Mar 27, 2018

Thanks for the report @andyboyne. The problem stems from the fact that we don't update the value attribute on number inputs until the field is blurred. We do this to avoid a bunch of unwanted behavior related to browser validation. cc @nhunzaker.

This should be resolved once we finally stop syncing the value attribute for controlled inputs #11896.

@nhunzaker
Copy link
Contributor

Yes. Actually I wonder if we should get a timeline together on this.

@laubesson
Copy link

As aweary mentionned it is a synching issue, the field is sync when the field is blurred.
So I added some console.log and I figured out that e.target.value and e.target.getAttribute("value") are not sync while the field is not blurred.
So a workaround is to add e.target.setAttribute("value",e.target.value); to force to update this value and then it works as expected.

       onChange={e => {
        console.log("target" , e.target.value);
        console.log("getAttribute value",  e.target.getAttribute("value"));
        e.target.setAttribute("value",e.target.value); 
        this.setState({value: e.target.value, step: e.target.value / 10});
      }}

@stiofand
Copy link

Nope, this is still an issue, it drives me crazy, we still haven't simplified controlled inputs by v16!

@JoelFickson
Copy link

JoelFickson commented Mar 26, 2022

If you are still finding problems with this issue, I suggest a solution that would so ideal.

    const CustomInput = () => {
      const dispatch = useDispatch();
      const [value, setValue] = useState < number > valueFromState;
      const onChange = (value: string) => {
        const localValue = Number(value);
        setValue(localValue);
        dispatch(setMyGlobalValue(localvalue));
      };

     return (
        <div>
          <input
            onChange={(event) => onChange(event.target.value)}
            type="number"
            value={value}
            min={0}
            step={0.25}
            className="text-input "
          />
        </div>
      );};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants