25
var ReactCompositeComponent = require('ReactCompositeComponent');
26
var ReactDOM = require('ReactDOM');
27
var ReactMount = require('ReactMount');
28
+var ReactUpdates = require('ReactUpdates');
29
30
var invariant = require('invariant');
31
var merge = require('merge');
35
36
var instancesByReactID = {};
37
38
+function forceUpdateIfMounted() {
39
+ /*jshint validthis:true */
40
+ if (this.isMounted()) {
41
+ this.forceUpdate();
42
+ }
43
+}
44
+
45
/**
46
* Implements an <input> native component that allows setting these optional
47
* props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
66
getInitialState: function() {
67
var defaultValue = this.props.defaultValue;
68
return {
61
- checked: this.props.defaultChecked || false,
62
- value: defaultValue != null ? defaultValue : null
69
+ initialChecked: this.props.defaultChecked || false,
70
+ initialValue: defaultValue != null ? defaultValue : null
71
};
72
},
73
66
- shouldComponentUpdate: function() {
67
- // Defer any updates to this component during the `onChange` handler.
68
- return !this._isChanging;
69
- },
70
-
74
render: function() {
75
// Clone `this.props` so we don't mutate the input.
76
var props = merge(this.props);
79
props.defaultValue = null;
80
81
var value = LinkedValueUtils.getValue(this);
79
- props.value = value != null ? value : this.state.value;
82
+ props.value = value != null ? value : this.state.initialValue;
83
84
var checked = LinkedValueUtils.getChecked(this);
82
- props.checked = checked != null ? checked : this.state.checked;
85
+ props.checked = checked != null ? checked : this.state.initialChecked;
86
87
props.onChange = this._handleChange;
88
122
var returnValue;
123
var onChange = LinkedValueUtils.getOnChange(this);
124
if (onChange) {
122
- this._isChanging = true;
125
returnValue = onChange.call(this, event);
124
- this._isChanging = false;
126
}
126
- this.setState({
127
- checked: event.target.checked,
128
- value: event.target.value
129
- });
127
+ // Here we use setImmediate to wait until all updates have propagated, which
128
+ // is important when using controlled components within layers:
129
+ // https://github.com/facebook/react/issues/1698
130
+ ReactUpdates.setImmediate(forceUpdateIfMounted, this);
131
132
var name = this.props.name;
133
if (this.props.type === 'radio' && name != null) {
165
'ReactDOMInput: Unknown radio button ID %s.',
166
otherID
167
);
167
- // In some cases, this will actually change the `checked` state value.
168
- // In other cases, there's no change but this forces a reconcile upon
169
- // which componentDidUpdate will reset the DOM property to whatever it
170
- // should be.
171
- otherInstance.setState({
172
- checked: false
173
- });
168
+ // If this is a controlled radio button group, forcing the input that
169
+ // was previously checked to update will cause it to be come re-checked
170
+ // as appropriate.
171
+ ReactUpdates.setImmediate(forceUpdateIfMounted, otherInstance);
172
}
173
}
174