mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Avoid validation warning when inputs change type (#7333)
For controlled inputs, `updateWrapper` was getting called before the `type` prop had a chance to update. This could lead to a case where switching from the `text` to `number` type caused a validation error that would prevent the proper input value from being assigned. This commit moves the call to `ReactDOMInput.updateWrapper` below `_updateProperties` to avoid this situation.
This commit is contained in:
committed by
Ben Alpert
parent
1fc5f284c0
commit
08a0895887
@@ -769,4 +769,25 @@ describe('ReactDOMInput', function() {
|
||||
);
|
||||
expect(input.value).toBe('hi');
|
||||
});
|
||||
|
||||
it('does not raise a validation warning when it switches types', function() {
|
||||
var Input = React.createClass({
|
||||
getInitialState() {
|
||||
return { type: 'number', value: 1000 };
|
||||
},
|
||||
render() {
|
||||
var { value, type } = this.state;
|
||||
return (<input onChange={() => {}} type={type} value={value} />);
|
||||
},
|
||||
});
|
||||
|
||||
var input = ReactTestUtils.renderIntoDocument(<Input />);
|
||||
var node = ReactDOM.findDOMNode(input);
|
||||
|
||||
// If the value is set before the type, a validation warning will raise and
|
||||
// the value will not be assigned.
|
||||
input.setState({ type: 'text', value: 'Test' });
|
||||
expect(node.value).toEqual('Test');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -907,7 +907,6 @@ ReactDOMComponent.Mixin = {
|
||||
nextProps = ReactDOMButton.getHostProps(this, nextProps);
|
||||
break;
|
||||
case 'input':
|
||||
ReactDOMInput.updateWrapper(this);
|
||||
lastProps = ReactDOMInput.getHostProps(this, lastProps);
|
||||
nextProps = ReactDOMInput.getHostProps(this, nextProps);
|
||||
break;
|
||||
@@ -920,7 +919,6 @@ ReactDOMComponent.Mixin = {
|
||||
nextProps = ReactDOMSelect.getHostProps(this, nextProps);
|
||||
break;
|
||||
case 'textarea':
|
||||
ReactDOMTextarea.updateWrapper(this);
|
||||
lastProps = ReactDOMTextarea.getHostProps(this, lastProps);
|
||||
nextProps = ReactDOMTextarea.getHostProps(this, nextProps);
|
||||
break;
|
||||
@@ -935,10 +933,21 @@ ReactDOMComponent.Mixin = {
|
||||
context
|
||||
);
|
||||
|
||||
if (this._tag === 'select') {
|
||||
// <select> value update needs to occur after <option> children
|
||||
// reconciliation
|
||||
transaction.getReactMountReady().enqueue(postUpdateSelectWrapper, this);
|
||||
switch (this._tag) {
|
||||
case 'input':
|
||||
// Update the wrapper around inputs *after* updating props. This has to
|
||||
// happen after `_updateDOMProperties`. Otherwise HTML5 input validations
|
||||
// raise warnings and prevent the new value from being assigned.
|
||||
ReactDOMInput.updateWrapper(this);
|
||||
break;
|
||||
case 'textarea':
|
||||
ReactDOMTextarea.updateWrapper(this);
|
||||
break;
|
||||
case 'select':
|
||||
// <select> value update needs to occur after <option> children
|
||||
// reconciliation
|
||||
transaction.getReactMountReady().enqueue(postUpdateSelectWrapper, this);
|
||||
break;
|
||||
}
|
||||
|
||||
if (__DEV__) {
|
||||
|
||||
Reference in New Issue
Block a user