mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Change LinkedValueMixin to a util class
This makes it clear that .getValue() is not a public API.
This commit is contained in:
@@ -39,7 +39,7 @@
|
||||
* });
|
||||
*
|
||||
* We have provided some sugary mixins to make the creation and
|
||||
* consumption of ReactLink easier; see LinkedValueMixin and LinkedStateMixin.
|
||||
* consumption of ReactLink easier; see LinkedValueUtils and LinkedStateMixin.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/**
|
||||
* Copyright 2013 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @providesModule LinkedValueMixin
|
||||
* @typechecks static-only
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var invariant = require('invariant');
|
||||
|
||||
var hasReadOnlyValue = {
|
||||
'checkbox': true,
|
||||
'hidden': true,
|
||||
'radio': true
|
||||
};
|
||||
|
||||
/**
|
||||
* Provide a linked `value` attribute for controlled forms. You should not use
|
||||
* this outside of the ReactDOM controlled form components.
|
||||
*/
|
||||
var LinkedValueMixin = {
|
||||
propTypes: {
|
||||
value: function(props, propName, componentName) {
|
||||
if (__DEV__) {
|
||||
if (props[propName] &&
|
||||
!hasReadOnlyValue[props.type] &&
|
||||
!props.onChange &&
|
||||
!props.readOnly &&
|
||||
!props.disabled) {
|
||||
console.warn(
|
||||
'You provided a `value` prop to a form field without an ' +
|
||||
'`onChange` handler. This will render a read-only field. If ' +
|
||||
'the field should be mutable use `defaultValue`. Otherwise, set ' +
|
||||
'either `onChange` or `readOnly`.'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_assertLink: function() {
|
||||
invariant(
|
||||
this.props.value == null && this.props.onChange == null,
|
||||
'Cannot provide a valueLink and a value or onChange event. If you ' +
|
||||
'want to use value or onChange, you probably don\'t want to use ' +
|
||||
'valueLink'
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {*} current value of the input either from value prop or link.
|
||||
*/
|
||||
getValue: function() {
|
||||
if (this.props.valueLink) {
|
||||
this._assertLink();
|
||||
return this.props.valueLink.value;
|
||||
}
|
||||
return this.props.value;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {function} change callback either from onChange prop or link.
|
||||
*/
|
||||
getOnChange: function() {
|
||||
if (this.props.valueLink) {
|
||||
this._assertLink();
|
||||
return this._handleLinkedValueChange;
|
||||
}
|
||||
return this.props.onChange;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {SyntheticEvent} e change event to handle
|
||||
*/
|
||||
_handleLinkedValueChange: function(e) {
|
||||
this.props.valueLink.requestChange(e.target.value);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = LinkedValueMixin;
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Copyright 2013 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @providesModule LinkedValueUtils
|
||||
* @typechecks static-only
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var invariant = require('invariant');
|
||||
|
||||
var hasReadOnlyValue = {
|
||||
'checkbox': true,
|
||||
'hidden': true,
|
||||
'radio': true
|
||||
};
|
||||
|
||||
function _assertLink(input) {
|
||||
invariant(
|
||||
input.props.value == null && input.props.onChange == null,
|
||||
'Cannot provide a valueLink and a value or onChange event. If you want ' +
|
||||
'to use value or onChange, you probably don\'t want to use valueLink.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SyntheticEvent} e change event to handle
|
||||
*/
|
||||
function _handleLinkedValueChange(e) {
|
||||
/*jshint validthis:true */
|
||||
this.props.valueLink.requestChange(e.target.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a linked `value` attribute for controlled forms. You should not use
|
||||
* this outside of the ReactDOM controlled form components.
|
||||
*/
|
||||
var LinkedValueUtils = {
|
||||
Mixin: {
|
||||
propTypes: {
|
||||
value: function(props, propName, componentName) {
|
||||
if (__DEV__) {
|
||||
if (props[propName] &&
|
||||
!hasReadOnlyValue[props.type] &&
|
||||
!props.onChange &&
|
||||
!props.readOnly &&
|
||||
!props.disabled) {
|
||||
console.warn(
|
||||
'You provided a `value` prop to a form field without an ' +
|
||||
'`onChange` handler. This will render a read-only field. If ' +
|
||||
'the field should be mutable use `defaultValue`. Otherwise, ' +
|
||||
'set either `onChange` or `readOnly`.'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {ReactComponent} input Form component
|
||||
* @return {*} current value of the input either from value prop or link.
|
||||
*/
|
||||
getValue: function(input) {
|
||||
if (input.props.valueLink) {
|
||||
_assertLink(input);
|
||||
return input.props.valueLink.value;
|
||||
}
|
||||
return input.props.value;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {ReactComponent} input Form component
|
||||
* @return {function} change callback either from onChange prop or link.
|
||||
*/
|
||||
getOnChange: function(input) {
|
||||
if (input.props.valueLink) {
|
||||
_assertLink(input);
|
||||
return _handleLinkedValueChange;
|
||||
}
|
||||
return input.props.onChange;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = LinkedValueUtils;
|
||||
@@ -18,9 +18,9 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
var DOMPropertyOperations = require('DOMPropertyOperations');
|
||||
var LinkedValueMixin = require('LinkedValueMixin');
|
||||
var AutoFocusMixin = require('AutoFocusMixin');
|
||||
var DOMPropertyOperations = require('DOMPropertyOperations');
|
||||
var LinkedValueUtils = require('LinkedValueUtils');
|
||||
var ReactCompositeComponent = require('ReactCompositeComponent');
|
||||
var ReactDOM = require('ReactDOM');
|
||||
var ReactMount = require('ReactMount');
|
||||
@@ -52,7 +52,7 @@ var instancesByReactID = {};
|
||||
var ReactDOMInput = ReactCompositeComponent.createClass({
|
||||
displayName: 'ReactDOMInput',
|
||||
|
||||
mixins: [LinkedValueMixin, AutoFocusMixin],
|
||||
mixins: [AutoFocusMixin, LinkedValueUtils.Mixin],
|
||||
|
||||
getInitialState: function() {
|
||||
var defaultValue = this.props.defaultValue;
|
||||
@@ -76,7 +76,7 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
|
||||
props.checked =
|
||||
this.props.checked != null ? this.props.checked : this.state.checked;
|
||||
|
||||
var value = this.getValue();
|
||||
var value = LinkedValueUtils.getValue(this);
|
||||
props.value = value != null ? value : this.state.value;
|
||||
|
||||
props.onChange = this._handleChange;
|
||||
@@ -105,7 +105,7 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
|
||||
);
|
||||
}
|
||||
|
||||
var value = this.getValue();
|
||||
var value = LinkedValueUtils.getValue(this);
|
||||
if (value != null) {
|
||||
// Cast `value` to a string to ensure the value is set correctly. While
|
||||
// browsers typically do this as necessary, jsdom doesn't.
|
||||
@@ -115,10 +115,10 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
|
||||
|
||||
_handleChange: function(event) {
|
||||
var returnValue;
|
||||
var onChange = this.getOnChange();
|
||||
var onChange = LinkedValueUtils.getOnChange(this);
|
||||
if (onChange) {
|
||||
this._isChanging = true;
|
||||
returnValue = onChange(event);
|
||||
returnValue = onChange.call(this, event);
|
||||
this._isChanging = false;
|
||||
}
|
||||
this.setState({
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
var LinkedValueMixin = require('LinkedValueMixin');
|
||||
var AutoFocusMixin = require('AutoFocusMixin');
|
||||
var LinkedValueUtils = require('LinkedValueUtils');
|
||||
var ReactCompositeComponent = require('ReactCompositeComponent');
|
||||
var ReactDOM = require('ReactDOM');
|
||||
|
||||
@@ -61,7 +61,7 @@ function selectValueType(props, propName, componentName) {
|
||||
function updateOptions() {
|
||||
/*jshint validthis:true */
|
||||
var multiple = this.props.multiple;
|
||||
var propValue = this.getValue();
|
||||
var propValue = LinkedValueUtils.getValue(this);
|
||||
var value = propValue != null ? propValue : this.state.value;
|
||||
var options = this.getDOMNode().options;
|
||||
var selectedValue, i, l;
|
||||
@@ -102,7 +102,7 @@ function updateOptions() {
|
||||
var ReactDOMSelect = ReactCompositeComponent.createClass({
|
||||
displayName: 'ReactDOMSelect',
|
||||
|
||||
mixins: [LinkedValueMixin, AutoFocusMixin],
|
||||
mixins: [AutoFocusMixin, LinkedValueUtils.Mixin],
|
||||
|
||||
propTypes: {
|
||||
defaultValue: selectValueType,
|
||||
@@ -142,10 +142,10 @@ var ReactDOMSelect = ReactCompositeComponent.createClass({
|
||||
|
||||
_handleChange: function(event) {
|
||||
var returnValue;
|
||||
var onChange = this.getOnChange();
|
||||
var onChange = LinkedValueUtils.getOnChange(this);
|
||||
if (onChange) {
|
||||
this._isChanging = true;
|
||||
returnValue = onChange(event);
|
||||
returnValue = onChange.call(this, event);
|
||||
this._isChanging = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
var DOMPropertyOperations = require('DOMPropertyOperations');
|
||||
var LinkedValueMixin = require('LinkedValueMixin');
|
||||
var AutoFocusMixin = require('AutoFocusMixin');
|
||||
var DOMPropertyOperations = require('DOMPropertyOperations');
|
||||
var LinkedValueUtils = require('LinkedValueUtils');
|
||||
var ReactCompositeComponent = require('ReactCompositeComponent');
|
||||
var ReactDOM = require('ReactDOM');
|
||||
|
||||
@@ -48,7 +48,7 @@ var textarea = ReactDOM.textarea;
|
||||
var ReactDOMTextarea = ReactCompositeComponent.createClass({
|
||||
displayName: 'ReactDOMTextarea',
|
||||
|
||||
mixins: [LinkedValueMixin, AutoFocusMixin],
|
||||
mixins: [AutoFocusMixin, LinkedValueUtils.Mixin],
|
||||
|
||||
getInitialState: function() {
|
||||
var defaultValue = this.props.defaultValue;
|
||||
@@ -78,7 +78,7 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
|
||||
if (defaultValue == null) {
|
||||
defaultValue = '';
|
||||
}
|
||||
var value = this.getValue();
|
||||
var value = LinkedValueUtils.getValue(this);
|
||||
return {
|
||||
// We save the initial value so that `ReactDOMComponent` doesn't update
|
||||
// `textContent` (unnecessary since we update value).
|
||||
@@ -97,7 +97,7 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
|
||||
render: function() {
|
||||
// Clone `this.props` so we don't mutate the input.
|
||||
var props = merge(this.props);
|
||||
var value = this.getValue();
|
||||
var value = LinkedValueUtils.getValue(this);
|
||||
|
||||
invariant(
|
||||
props.dangerouslySetInnerHTML == null,
|
||||
@@ -114,7 +114,7 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
|
||||
},
|
||||
|
||||
componentDidUpdate: function(prevProps, prevState, prevContext) {
|
||||
var value = this.getValue();
|
||||
var value = LinkedValueUtils.getValue(this);
|
||||
if (value != null) {
|
||||
var rootNode = this.getDOMNode();
|
||||
// Cast `value` to a string to ensure the value is set correctly. While
|
||||
@@ -125,10 +125,10 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
|
||||
|
||||
_handleChange: function(event) {
|
||||
var returnValue;
|
||||
var onChange = this.getOnChange();
|
||||
var onChange = LinkedValueUtils.getOnChange(this);
|
||||
if (onChange) {
|
||||
this._isChanging = true;
|
||||
returnValue = onChange(event);
|
||||
returnValue = onChange.call(this, event);
|
||||
this._isChanging = false;
|
||||
}
|
||||
this.setState({value: event.target.value});
|
||||
|
||||
Reference in New Issue
Block a user