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

Warning when changing the type and value of an input field #6441

Closed
mathisonian opened this issue Apr 7, 2016 · 13 comments · Fixed by #7333
Closed

Warning when changing the type and value of an input field #6441

mathisonian opened this issue Apr 7, 2016 · 13 comments · Fixed by #7333

Comments

@mathisonian
Copy link

In my render method I have something like

<input type={dynamicTypeValue} value={dynamicValue} />

If I first render this input as a number, (e.g. dynamicTypeValue = 'number'; dynamicValue = 5) but then change the input to a string: (dynamicTypeValue = 'string'; dynamicValue = '01/01/2016') I get a warning
that the new value is not a valid number:

The specified value "01/01/2000" is not a valid number. The value must match to the following regular expression: -?(\d+|\d+\.\d+|\.\d+)([eE][-+]?\d+)?
DOMPropertyOperations.js:142 The specified value "01/01/2012" is not a valid number. The value must match to the following regular expression: -?(\d+|\d+\.\d+|\.\d+)([eE][-+]?\d+)?

screen shot 2016-04-07 at 6 07 45 pm

Is this expected behavior?

@jimfb
Copy link
Contributor

jimfb commented Apr 7, 2016

Looks like we're applying the prop changes in a bad order. The logic to get this right is solvable in general (for known types), but could be complex to get perfect if we want to minimize DOM operations.

@jimfb jimfb added the Type: Bug label Apr 7, 2016
@sophiebits
Copy link
Collaborator

I'm surprised that this particular case is problematic because this code should ensure that we always set .type before any other attributes on an <input>:

Not sure why that isn't working as designed. It's not totally clear to me whether setting type first always solves cases like these or setting type first would simply cause the same warning when switching the other way.

(See also #2242, which is something we may want to have happen but may be difficult to implement cleanly in the current system. It was easier when we had full composite wrappers for these components but we no longer do. Creating a new element whenever the type changes could be surprising because it would mean that the ref to that component changes during the lifetime of the component which we never have elsewhere.)

@sophiebits
Copy link
Collaborator

The easiest workaround here is to set a key on the input that changes with the type so that a new input element is created when the type changes.

@gaearon
Copy link
Collaborator

gaearon commented Apr 30, 2016

Could be caused by Object.assign V8 order bug? Or was this before 15?

@tisghans
Copy link

tisghans commented May 1, 2016

@gaearon this is still in the 15 release

@jimfb
Copy link
Contributor

jimfb commented May 1, 2016

@gurinderhans Which browser? Also, can you provide a jsfiddle that demonstrates the issue?

@tisghans
Copy link

tisghans commented May 1, 2016

@jimfb Here you go.
Browser: Chrome 50.0.2661.86 (64-bit)
JSFiddle: https://jsfiddle.net/mb90na04/1/

@tisghans
Copy link

tisghans commented May 1, 2016

Following the chrome debugger I found this:
There's this line of code, https://github.com/facebook/react/blob/master/src/renderers/dom/shared/ReactDOMComponent.js#L829, which after makes a call to https://github.com/facebook/react/blob/master/src/renderers/dom/client/wrappers/ReactDOMInput.js#L221 and then the value of the input is tried to be changed while _updateDOMProperties hasn't yet been called to update the element type attribute, thus the warning is generated. Once _updateDOMProperties is called, type gets set before value, like it is suppose to and everything goes according to plan.

PS: Of Course, removing the call to ReactDOMInput.updateWrapper, inside the switch case rids the warning, but this may be required for some other cases as I also notice it gets called if element type is textarea.

You could check for type change, and not set value, or update type and then set value inside ReactDOMInput.updateWrapper. I'm also wondering why the call is required for cases like <input> or <textarea>

@aweary
Copy link
Contributor

aweary commented Jul 11, 2016

Here is a simpler case reproducing the issue: https://jsfiddle.net/97gr5e65/1/

It seems to only happen if changing from number to text. I'm also not able to reproduce the warning in Safari or Firefox on OS X. It also doesn't seem to occur using ReactTestUtils.

@nhunzaker
Copy link
Contributor

This was an interesting bug to check out, so I did some poking around. My initial thought was just to assign type before value in the updateWrapper. Is this sane?

https://github.com/facebook/react/compare/master...nhunzaker:nh-input-change-fix?expand=1

It eliminates the bug, but it's too simple. It feels shallow. What do you think?

@sophiebits
Copy link
Collaborator

sophiebits commented Jul 22, 2016

Can we move the .updateWrapper calls below the _updateDOMChildren call (splitting them out from the getNativeProps calls)? I think that's the best solution here and looks like it should work.

@nhunzaker
Copy link
Contributor

Yes. I was also able to get test coverage on this. The value is nullified by the DOM when the type changes such that the the value is no longer valid, or if a new value is assigned that is not valid.

Unrelated, it's pretty cool that JSDOM picks this up.

Done in #7333

@mariorodriguespt
Copy link

Still happens with version 16.4.1

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

Successfully merging a pull request may close this issue.

8 participants