diff --git a/src/browser/ReactDOM.js b/src/browser/ReactDOM.js
index 4906cc47d8..32bb9e3b60 100644
--- a/src/browser/ReactDOM.js
+++ b/src/browser/ReactDOM.js
@@ -20,7 +20,6 @@
"use strict";
var ReactDescriptor = require('ReactDescriptor');
-var ReactDescriptorValidator = require('ReactDescriptorValidator');
var ReactDOMComponent = require('ReactDOMComponent');
var mergeInto = require('mergeInto');
@@ -51,12 +50,6 @@ function createDOMComponentClass(omitClose, tag) {
var ConvenienceConstructor = ReactDescriptor.createFactory(Constructor);
- if (__DEV__) {
- return ReactDescriptorValidator.createFactory(
- ConvenienceConstructor
- );
- }
-
return ConvenienceConstructor;
}
diff --git a/src/core/ReactCompositeComponent.js b/src/core/ReactCompositeComponent.js
index 4622314281..372126221c 100644
--- a/src/core/ReactCompositeComponent.js
+++ b/src/core/ReactCompositeComponent.js
@@ -22,7 +22,6 @@ var ReactComponent = require('ReactComponent');
var ReactContext = require('ReactContext');
var ReactCurrentOwner = require('ReactCurrentOwner');
var ReactDescriptor = require('ReactDescriptor');
-var ReactDescriptorValidator = require('ReactDescriptorValidator');
var ReactEmptyComponent = require('ReactEmptyComponent');
var ReactErrorUtils = require('ReactErrorUtils');
var ReactOwner = require('ReactOwner');
@@ -329,17 +328,18 @@ var ReactCompositeComponentInterface = {
* which all other static methods are defined.
*/
var RESERVED_SPEC_KEYS = {
- displayName: function(Constructor, displayName) {
- Constructor.displayName = displayName;
+ displayName: function(ConvenienceConstructor, displayName) {
+ ConvenienceConstructor.type.displayName = displayName;
},
- mixins: function(Constructor, mixins) {
+ mixins: function(ConvenienceConstructor, mixins) {
if (mixins) {
for (var i = 0; i < mixins.length; i++) {
- mixSpecIntoComponent(Constructor, mixins[i]);
+ mixSpecIntoComponent(ConvenienceConstructor, mixins[i]);
}
}
},
- childContextTypes: function(Constructor, childContextTypes) {
+ childContextTypes: function(ConvenienceConstructor, childContextTypes) {
+ var Constructor = ConvenienceConstructor.type;
validateTypeDef(
Constructor,
childContextTypes,
@@ -350,7 +350,8 @@ var RESERVED_SPEC_KEYS = {
childContextTypes
);
},
- contextTypes: function(Constructor, contextTypes) {
+ contextTypes: function(ConvenienceConstructor, contextTypes) {
+ var Constructor = ConvenienceConstructor.type;
validateTypeDef(
Constructor,
contextTypes,
@@ -358,21 +359,8 @@ var RESERVED_SPEC_KEYS = {
);
Constructor.contextTypes = merge(Constructor.contextTypes, contextTypes);
},
- /**
- * Special case getDefaultProps which should move into statics but requires
- * automatic merging.
- */
- getDefaultProps: function(Constructor, getDefaultProps) {
- if (Constructor.getDefaultProps) {
- Constructor.getDefaultProps = createMergedResultFunction(
- Constructor.getDefaultProps,
- getDefaultProps
- );
- } else {
- Constructor.getDefaultProps = getDefaultProps;
- }
- },
- propTypes: function(Constructor, propTypes) {
+ propTypes: function(ConvenienceConstructor, propTypes) {
+ var Constructor = ConvenienceConstructor.type;
validateTypeDef(
Constructor,
propTypes,
@@ -380,8 +368,8 @@ var RESERVED_SPEC_KEYS = {
);
Constructor.propTypes = merge(Constructor.propTypes, propTypes);
},
- statics: function(Constructor, statics) {
- mixStaticSpecIntoComponent(Constructor, statics);
+ statics: function(ConvenienceConstructor, statics) {
+ mixStaticSpecIntoComponent(ConvenienceConstructor, statics);
}
};
@@ -449,7 +437,7 @@ function validateLifeCycleOnReplaceState(instance) {
* Custom version of `mixInto` which handles policy validation and reserved
* specification keys when building `ReactCompositeComponent` classses.
*/
-function mixSpecIntoComponent(Constructor, spec) {
+function mixSpecIntoComponent(ConvenienceConstructor, spec) {
invariant(
!ReactDescriptor.isValidFactory(spec),
'ReactCompositeComponent: You\'re attempting to ' +
@@ -461,6 +449,7 @@ function mixSpecIntoComponent(Constructor, spec) {
'use a component as a mixin. Instead, just use a regular object.'
);
+ var Constructor = ConvenienceConstructor.type;
var proto = Constructor.prototype;
for (var name in spec) {
var property = spec[name];
@@ -471,7 +460,7 @@ function mixSpecIntoComponent(Constructor, spec) {
validateMethodOverride(proto, name);
if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
- RESERVED_SPEC_KEYS[name](Constructor, property);
+ RESERVED_SPEC_KEYS[name](ConvenienceConstructor, property);
} else {
// Setup methods on prototype:
// The following member methods should not be automatically bound:
@@ -532,7 +521,7 @@ function mixSpecIntoComponent(Constructor, spec) {
}
}
-function mixStaticSpecIntoComponent(Constructor, statics) {
+function mixStaticSpecIntoComponent(ConvenienceConstructor, statics) {
if (!statics) {
return;
}
@@ -542,10 +531,10 @@ function mixStaticSpecIntoComponent(Constructor, statics) {
continue;
}
- var isInherited = name in Constructor;
+ var isInherited = name in ConvenienceConstructor;
var result = property;
if (isInherited) {
- var existingProperty = Constructor[name];
+ var existingProperty = ConvenienceConstructor[name];
var existingType = typeof existingProperty;
var propertyType = typeof property;
invariant(
@@ -558,7 +547,8 @@ function mixStaticSpecIntoComponent(Constructor, statics) {
);
result = createChainedFunction(existingProperty, property);
}
- Constructor[name] = result;
+ ConvenienceConstructor[name] = result;
+ ConvenienceConstructor.type[name] = result;
}
}
@@ -733,6 +723,7 @@ var ReactCompositeComponentMixin = {
this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;
this.context = this._processContext(this._descriptor._context);
+ this._defaultProps = this.getDefaultProps ? this.getDefaultProps() : null;
this.props = this._processProps(this.props);
if (this.__reactAutoBindMap) {
@@ -790,6 +781,8 @@ var ReactCompositeComponentMixin = {
}
this._compositeLifeCycleState = null;
+ this._defaultProps = null;
+
this._renderedComponent.unmountComponent();
this._renderedComponent = null;
@@ -928,6 +921,12 @@ var ReactCompositeComponentMixin = {
*/
_processProps: function(newProps) {
var props = merge(newProps);
+ var defaultProps = this._defaultProps;
+ for (var propName in defaultProps) {
+ if (typeof props[propName] === 'undefined') {
+ props[propName] = defaultProps[propName];
+ }
+ }
if (__DEV__) {
var propTypes = this.constructor.propTypes;
if (propTypes) {
@@ -946,8 +945,6 @@ var ReactCompositeComponentMixin = {
* @private
*/
_checkPropTypes: function(propTypes, props, location) {
- // TODO: Stop validating prop types here and only use the descriptor
- // validation.
var componentName = this.constructor.displayName;
for (var propName in propTypes) {
if (propTypes.hasOwnProperty(propName)) {
@@ -1313,11 +1310,16 @@ var ReactCompositeComponent = {
Constructor.prototype = new ReactCompositeComponentBase();
Constructor.prototype.constructor = Constructor;
+ var ConvenienceConstructor = ReactDescriptor.createFactory(Constructor);
+
+ // TODO: Move statics off of the convenience constructor. That way the
+ // factory can be created independently from the main class.
+
injectedMixins.forEach(
- mixSpecIntoComponent.bind(null, Constructor)
+ mixSpecIntoComponent.bind(null, ConvenienceConstructor)
);
- mixSpecIntoComponent(Constructor, spec);
+ mixSpecIntoComponent(ConvenienceConstructor, spec);
invariant(
Constructor.prototype.render,
@@ -1346,17 +1348,7 @@ var ReactCompositeComponent = {
}
}
- var descriptorFactory = ReactDescriptor.createFactory(Constructor);
-
- if (__DEV__) {
- return ReactDescriptorValidator.createFactory(
- descriptorFactory,
- Constructor.propTypes,
- Constructor.contextTypes
- );
- }
-
- return descriptorFactory;
+ return ConvenienceConstructor;
},
injection: {
diff --git a/src/core/ReactDescriptor.js b/src/core/ReactDescriptor.js
index cdcaf6930c..0c3cdbf617 100644
--- a/src/core/ReactDescriptor.js
+++ b/src/core/ReactDescriptor.js
@@ -21,9 +21,165 @@
var ReactContext = require('ReactContext');
var ReactCurrentOwner = require('ReactCurrentOwner');
-var merge = require('merge');
+var monitorCodeUse = require('monitorCodeUse');
var warning = require('warning');
+/**
+ * Warn if there's no key explicitly set on dynamic arrays of children or
+ * object keys are not valid. This allows us to keep track of children between
+ * updates.
+ */
+var ownerHasKeyUseWarning = {
+ 'react_key_warning': {},
+ 'react_numeric_key_warning': {}
+};
+var ownerHasMonitoredObjectMap = {};
+
+var NUMERIC_PROPERTY_REGEX = /^\d+$/;
+
+/**
+ * Gets the current owner's displayName for use in warnings.
+ *
+ * @internal
+ * @return {?string} Display name or undefined
+ */
+function getCurrentOwnerDisplayName() {
+ var current = ReactCurrentOwner.current;
+ return current && current.constructor.displayName || undefined;
+}
+
+/**
+ * Warn if the component doesn't have an explicit key assigned to it.
+ * This component is in an array. The array could grow and shrink or be
+ * reordered. All children that haven't already been validated are required to
+ * have a "key" property assigned to it.
+ *
+ * @internal
+ * @param {ReactComponent} component Component that requires a key.
+ * @param {*} parentType component's parent's type.
+ */
+function validateExplicitKey(component, parentType) {
+ if (component._store.validated || component.props.key != null) {
+ return;
+ }
+ component._store.validated = true;
+
+ warnAndMonitorForKeyUse(
+ 'react_key_warning',
+ 'Each child in an array should have a unique "key" prop.',
+ component,
+ parentType
+ );
+}
+
+/**
+ * Warn if the key is being defined as an object property but has an incorrect
+ * value.
+ *
+ * @internal
+ * @param {string} name Property name of the key.
+ * @param {ReactComponent} component Component that requires a key.
+ * @param {*} parentType component's parent's type.
+ */
+function validatePropertyKey(name, component, parentType) {
+ if (!NUMERIC_PROPERTY_REGEX.test(name)) {
+ return;
+ }
+ warnAndMonitorForKeyUse(
+ 'react_numeric_key_warning',
+ 'Child objects should have non-numeric keys so ordering is preserved.',
+ component,
+ parentType
+ );
+}
+
+/**
+ * Shared warning and monitoring code for the key warnings.
+ *
+ * @internal
+ * @param {string} warningID The id used when logging.
+ * @param {string} message The base warning that gets output.
+ * @param {ReactComponent} component Component that requires a key.
+ * @param {*} parentType component's parent's type.
+ */
+function warnAndMonitorForKeyUse(warningID, message, component, parentType) {
+ var ownerName = getCurrentOwnerDisplayName();
+ var parentName = parentType.displayName;
+
+ var useName = ownerName || parentName;
+ var memoizer = ownerHasKeyUseWarning[warningID];
+ if (memoizer.hasOwnProperty(useName)) {
+ return;
+ }
+ memoizer[useName] = true;
+
+ message += ownerName ?
+ ` Check the render method of ${ownerName}.` :
+ ` Check the renderComponent call using <${parentName}>.`;
+
+ // Usually the current owner is the offender, but if it accepts children as a
+ // property, it may be the creator of the child that's responsible for
+ // assigning it a key.
+ var childOwnerName = null;
+ if (component._owner && component._owner !== ReactCurrentOwner.current) {
+ // Name of the component that originally created this child.
+ childOwnerName = component._owner.constructor.displayName;
+
+ message += ` It was passed a child from ${childOwnerName}.`;
+ }
+
+ message += ' See http://fb.me/react-warning-keys for more information.';
+ monitorCodeUse(warningID, {
+ component: useName,
+ componentOwner: childOwnerName
+ });
+ console.warn(message);
+}
+
+/**
+ * Log that we're using an object map. We're considering deprecating this
+ * feature and replace it with proper Map and ImmutableMap data structures.
+ *
+ * @internal
+ */
+function monitorUseOfObjectMap() {
+ var currentName = getCurrentOwnerDisplayName() || '';
+ if (ownerHasMonitoredObjectMap.hasOwnProperty(currentName)) {
+ return;
+ }
+ ownerHasMonitoredObjectMap[currentName] = true;
+ monitorCodeUse('react_object_map_children');
+}
+
+/**
+ * Ensure that every component either is passed in a static location, in an
+ * array with an explicit keys property defined, or in an object literal
+ * with valid key property.
+ *
+ * @internal
+ * @param {*} component Statically passed child of any type.
+ * @param {*} parentType component's parent's type.
+ * @return {boolean}
+ */
+function validateChildKeys(component, parentType) {
+ if (Array.isArray(component)) {
+ for (var i = 0; i < component.length; i++) {
+ var child = component[i];
+ if (ReactDescriptor.isValidDescriptor(child)) {
+ validateExplicitKey(child, parentType);
+ }
+ }
+ } else if (ReactDescriptor.isValidDescriptor(component)) {
+ // This component was passed in a valid location.
+ component._store.validated = true;
+ } else if (component && typeof component === 'object') {
+ monitorUseOfObjectMap();
+ for (var name in component) {
+ validatePropertyKey(name, component[name], parentType);
+ }
+ }
+}
+
/**
* Warn for mutations.
*
@@ -81,26 +237,6 @@ function defineMutationMembrane(prototype) {
}
}
-/**
- * Transfer static properties from the source to the target. Functions are
- * rebound to have this reflect the original source.
- */
-function proxyStaticMethods(target, source) {
- if (typeof source !== 'function') {
- return;
- }
- for (var key in source) {
- if (source.hasOwnProperty(key)) {
- var value = source[key];
- if (typeof value === 'function') {
- target[key] = value.bind(source);
- } else {
- target[key] = value;
- }
- }
- }
-}
-
/**
* Base constructor for all React descriptors. This is only used to make this
* work with a dynamic instanceof check. Nothing should live on this prototype.
@@ -118,44 +254,29 @@ ReactDescriptor.createFactory = function(type) {
var descriptorPrototype = Object.create(ReactDescriptor.prototype);
- var defaultProps = type.getDefaultProps && type.getDefaultProps();
-
var factory = function(props, children) {
- // For consistency we currently allocate a new object for every descriptor.
- // This protects the descriptor from being mutated by the original props
- // object being mutated. It also protects the original props object from
- // being mutated by children arguments and default props. This behavior
- // comes with a performance cost and could be deprecated in the future.
- // It could also be optimized with a smarter JSX transform.
if (props == null) {
props = {};
- } else if (typeof props === 'object') {
- props = merge(props);
}
- // Children can be more than one argument, and those are transferred onto
- // the newly allocated props object.
+ // Children can be more than one argument
var childrenLength = arguments.length - 1;
if (childrenLength === 1) {
+ if (__DEV__) {
+ validateChildKeys(children, type);
+ }
props.children = children;
} else if (childrenLength > 1) {
var childArray = Array(childrenLength);
for (var i = 0; i < childrenLength; i++) {
+ if (__DEV__) {
+ validateChildKeys(arguments[i + 1], type);
+ }
childArray[i] = arguments[i + 1];
}
props.children = childArray;
}
- // Resolve default props
- if (defaultProps) {
- for (var propName in defaultProps) {
- if (typeof props[propName] === 'undefined') {
- props[propName] = defaultProps[propName];
- }
- }
- }
-
- // Initialize the descriptor object
var descriptor = Object.create(descriptorPrototype);
// Record the component responsible for creating this descriptor.
@@ -168,13 +289,10 @@ ReactDescriptor.createFactory = function(type) {
if (__DEV__) {
// The validation flag and props are currently mutative. We put them on
// an external backing store so that we can freeze the whole object.
- // This can be replaced with a WeakMap once they are implemented in
- // commonly used development environments.
descriptor._store = { validated: false, props: props };
// We're not allowed to set props directly on the object so we early
- // return and rely on the prototype membrane to forward to the backing
- // store.
+ // return and rely on the prototype membrane toward to the backing store.
if (useMutationMembrane) {
Object.freeze(descriptor);
return descriptor;
@@ -183,6 +301,7 @@ ReactDescriptor.createFactory = function(type) {
descriptor.props = props;
return descriptor;
+
};
// Currently we expose the prototype of the descriptor so that
@@ -197,8 +316,6 @@ ReactDescriptor.createFactory = function(type) {
factory.type = type;
descriptorPrototype.type = type;
- proxyStaticMethods(factory, type);
-
// Expose a unique constructor on the prototype is that this works with type
// systems that compare constructor properties: .constructor === Foo
// This may be controversial since it requires a known factory function.
diff --git a/src/core/ReactDescriptorValidator.js b/src/core/ReactDescriptorValidator.js
deleted file mode 100644
index e6e23966aa..0000000000
--- a/src/core/ReactDescriptorValidator.js
+++ /dev/null
@@ -1,283 +0,0 @@
-/**
- * Copyright 2014 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 ReactDescriptorValidator
- */
-
-/**
- * ReactDescriptorValidator provides a wrapper around a descriptor factory
- * which validates the props passed to the descriptor. This is intended to be
- * used only in DEV and could be replaced by a static type checker for languages
- * that support it.
- */
-
-"use strict";
-
-var ReactDescriptor = require('ReactDescriptor');
-var ReactPropTypeLocations = require('ReactPropTypeLocations');
-var ReactCurrentOwner = require('ReactCurrentOwner');
-
-var monitorCodeUse = require('monitorCodeUse');
-
-/**
- * Warn if there's no key explicitly set on dynamic arrays of children or
- * object keys are not valid. This allows us to keep track of children between
- * updates.
- */
-var ownerHasKeyUseWarning = {
- 'react_key_warning': {},
- 'react_numeric_key_warning': {}
-};
-var ownerHasMonitoredObjectMap = {};
-
-var loggedTypeFailures = {};
-
-var NUMERIC_PROPERTY_REGEX = /^\d+$/;
-
-/**
- * Gets the current owner's displayName for use in warnings.
- *
- * @internal
- * @return {?string} Display name or undefined
- */
-function getCurrentOwnerDisplayName() {
- var current = ReactCurrentOwner.current;
- return current && current.constructor.displayName || undefined;
-}
-
-/**
- * Warn if the component doesn't have an explicit key assigned to it.
- * This component is in an array. The array could grow and shrink or be
- * reordered. All children that haven't already been validated are required to
- * have a "key" property assigned to it.
- *
- * @internal
- * @param {ReactComponent} component Component that requires a key.
- * @param {*} parentType component's parent's type.
- */
-function validateExplicitKey(component, parentType) {
- if (component._store.validated || component.props.key != null) {
- return;
- }
- component._store.validated = true;
-
- warnAndMonitorForKeyUse(
- 'react_key_warning',
- 'Each child in an array should have a unique "key" prop.',
- component,
- parentType
- );
-}
-
-/**
- * Warn if the key is being defined as an object property but has an incorrect
- * value.
- *
- * @internal
- * @param {string} name Property name of the key.
- * @param {ReactComponent} component Component that requires a key.
- * @param {*} parentType component's parent's type.
- */
-function validatePropertyKey(name, component, parentType) {
- if (!NUMERIC_PROPERTY_REGEX.test(name)) {
- return;
- }
- warnAndMonitorForKeyUse(
- 'react_numeric_key_warning',
- 'Child objects should have non-numeric keys so ordering is preserved.',
- component,
- parentType
- );
-}
-
-/**
- * Shared warning and monitoring code for the key warnings.
- *
- * @internal
- * @param {string} warningID The id used when logging.
- * @param {string} message The base warning that gets output.
- * @param {ReactComponent} component Component that requires a key.
- * @param {*} parentType component's parent's type.
- */
-function warnAndMonitorForKeyUse(warningID, message, component, parentType) {
- var ownerName = getCurrentOwnerDisplayName();
- var parentName = parentType.displayName;
-
- var useName = ownerName || parentName;
- var memoizer = ownerHasKeyUseWarning[warningID];
- if (memoizer.hasOwnProperty(useName)) {
- return;
- }
- memoizer[useName] = true;
-
- message += ownerName ?
- ` Check the render method of ${ownerName}.` :
- ` Check the renderComponent call using <${parentName}>.`;
-
- // Usually the current owner is the offender, but if it accepts children as a
- // property, it may be the creator of the child that's responsible for
- // assigning it a key.
- var childOwnerName = null;
- if (component._owner && component._owner !== ReactCurrentOwner.current) {
- // Name of the component that originally created this child.
- childOwnerName = component._owner.constructor.displayName;
-
- message += ` It was passed a child from ${childOwnerName}.`;
- }
-
- message += ' See http://fb.me/react-warning-keys for more information.';
- monitorCodeUse(warningID, {
- component: useName,
- componentOwner: childOwnerName
- });
- console.warn(message);
-}
-
-/**
- * Log that we're using an object map. We're considering deprecating this
- * feature and replace it with proper Map and ImmutableMap data structures.
- *
- * @internal
- */
-function monitorUseOfObjectMap() {
- var currentName = getCurrentOwnerDisplayName() || '';
- if (ownerHasMonitoredObjectMap.hasOwnProperty(currentName)) {
- return;
- }
- ownerHasMonitoredObjectMap[currentName] = true;
- monitorCodeUse('react_object_map_children');
-}
-
-/**
- * Ensure that every component either is passed in a static location, in an
- * array with an explicit keys property defined, or in an object literal
- * with valid key property.
- *
- * @internal
- * @param {*} component Statically passed child of any type.
- * @param {*} parentType component's parent's type.
- * @return {boolean}
- */
-function validateChildKeys(component, parentType) {
- if (Array.isArray(component)) {
- for (var i = 0; i < component.length; i++) {
- var child = component[i];
- if (ReactDescriptor.isValidDescriptor(child)) {
- validateExplicitKey(child, parentType);
- }
- }
- } else if (ReactDescriptor.isValidDescriptor(component)) {
- // This component was passed in a valid location.
- component._store.validated = true;
- } else if (component && typeof component === 'object') {
- monitorUseOfObjectMap();
- for (var name in component) {
- validatePropertyKey(name, component[name], parentType);
- }
- }
-}
-
-/**
- * Assert that the props are valid
- *
- * @param {string} componentName Name of the component for error messages.
- * @param {object} propTypes Map of prop name to a ReactPropType
- * @param {object} props
- * @param {string} location e.g. "prop", "context", "child context"
- * @private
- */
-function checkPropTypes(componentName, propTypes, props, location) {
- for (var propName in propTypes) {
- if (propTypes.hasOwnProperty(propName)) {
- var error;
- // Prop type validation may throw. In case they do, we don't want to
- // fail the render phase where it didn't fail before. So we log it.
- // After these have been cleaned up, we'll let them throw.
- try {
- error = propTypes[propName](props, propName, componentName, location);
- } catch (ex) {
- error = ex;
- }
- if (error instanceof Error && !(error.message in loggedTypeFailures)) {
- // Only monitor this failure once because there tends to be a lot of the
- // same error.
- loggedTypeFailures[error.message] = true;
- // This will soon use the warning module
- monitorCodeUse(
- 'react_failed_descriptor_type_check',
- { message: error.message }
- );
- }
- }
- }
-}
-
-var ReactDescriptorValidator = {
-
- /**
- * Wraps a descriptor factory function in another function which validates
- * the props and context of the descriptor and warns about any failed type
- * checks.
- *
- * @param {function} factory The original descriptor factory
- * @param {object?} propTypes A prop type definition set
- * @param {object?} contextTypes A context type definition set
- * @return {object} The component descriptor, which may be invalid.
- * @private
- */
- createFactory: function(factory, propTypes, contextTypes) {
- var validatedFactory = function(props, children) {
- var descriptor = factory.apply(this, arguments);
-
- for (var i = 1; i < arguments.length; i++) {
- validateChildKeys(arguments[i], descriptor.type);
- }
-
- var name = descriptor.type.displayName;
- if (propTypes) {
- checkPropTypes(
- name,
- propTypes,
- descriptor.props,
- ReactPropTypeLocations.prop
- );
- }
- if (contextTypes) {
- checkPropTypes(
- name,
- contextTypes,
- descriptor._context,
- ReactPropTypeLocations.context
- );
- }
- return descriptor;
- };
-
- validatedFactory.prototype = factory.prototype;
- validatedFactory.type = factory.type;
-
- // Copy static properties
- for (var key in factory) {
- if (factory.hasOwnProperty(key)) {
- validatedFactory[key] = factory[key];
- }
- }
-
- return validatedFactory;
- }
-
-};
-
-module.exports = ReactDescriptorValidator;
diff --git a/src/core/__tests__/ReactPropTypes-test.js b/src/core/__tests__/ReactPropTypes-test.js
index 1316231945..7177c17f16 100644
--- a/src/core/__tests__/ReactPropTypes-test.js
+++ b/src/core/__tests__/ReactPropTypes-test.js
@@ -614,7 +614,7 @@ describe('Custom validator', function() {
var instance = ;
instance = ReactTestUtils.renderIntoDocument(instance);
- expect(spy.argsForCall.length).toBe(2); // temp double validation
+ expect(spy.argsForCall.length).toBe(1);
expect(spy.argsForCall[0][1]).toBe('num');
expect(spy.argsForCall[0][2]).toBe('Component');
});
@@ -632,7 +632,7 @@ describe('Custom validator', function() {
var instance = ;
instance = ReactTestUtils.renderIntoDocument(instance);
- expect(spy.argsForCall.length).toBe(2); // temp double validation
+ expect(spy.argsForCall.length).toBe(1);
});
it('should have received the validator\'s return value', function() {