@samitouri / QOS-React-2 / commits / 4d8f0449d9

React.isValidClass

Sometimes you may need to detect if a value is a valid React class constructor. This enables that and prevents future consumers from getting caught in the trap of depending on an internal implementation detail we might change. Currently this works for classes created with `React.createClass` as well as `React.DOM.*`.

Paul O'Shannessy committed Aug 29, 2013 at 17:32 UTC 4d8f0449d9d08528cc1aaba0aa09d1d90e12d3dd
4 files changed +46 -3
src/core/React.js
+1
@@ -50,6 +50,7 @@ var React = {
50 ),
51 renderComponentToString: ReactServerRendering.renderComponentToString,
52 unmountAndReleaseReactRootNode: ReactMount.unmountAndReleaseReactRootNode,
53 + isValidClass: ReactCompositeComponent.isValidClass,
54 isValidComponent: ReactComponent.isValidComponent
55 };
56
src/core/ReactCompositeComponent.js
+13
@@ -956,6 +956,19 @@ var ReactCompositeComponent = {
956 return ConvenienceConstructor;
957 },
958
959 + /**
960 + * Checks if a value is a valid component constructor.
961 + *
962 + * @param {*}
963 + * @return {boolean}
964 + * @public
965 + */
966 + isValidClass: function(componentClass) {
967 + return componentClass instanceof Function &&
968 + 'componentConstructor' in componentClass &&
969 + componentClass.componentConstructor instanceof Function;
970 + },
971 +
972 /**
973 * TODO: Delete this when all callers have been updated to rely on this
974 * behavior being the default.
src/core/__tests__/ReactCompositeComponent-test.js
+26
@@ -381,4 +381,30 @@ describe('ReactCompositeComponent', function() {
381 );
382 });
383
384 + it('should detect valid CompositeComponent classes', function() {
385 + var Component = React.createClass({
386 + render: function() {
387 + return <div/>;
388 + }
389 + });
390 +
391 + expect(React.isValidClass(Component)).toBe(true);
392 + });
393 +
394 + it('should detect invalid CompositeComponent classes', function() {
395 + var FnComponent = function() {
396 + return false;
397 + }
398 +
399 + var NullComponent = null;
400 +
401 + var TrickFnComponent = function() {
402 + return true;
403 + }
404 + TrickFnComponent.componentConstructor = true;
405 +
406 + expect(React.isValidClass(FnComponent)).toBe(false);
407 + expect(React.isValidClass(NullComponent)).toBe(false);
408 + expect(React.isValidClass(TrickFnComponent)).toBe(false);
409 + });
410 });
src/core/__tests__/ReactDOM-test.js
+6 -3
@@ -23,11 +23,10 @@
23
24 var React = require('React');
25 var ReactDOM = require('ReactDOM');
26 -var ReactTestUtils = require('ReactTestUtils');
27 -var React = require('React');
26 var ReactMount = require('ReactMount');
27 +var ReactTestUtils = require('ReactTestUtils');
28
30 -describe('ref swapping', function() {
29 +describe('ReactDOM', function() {
30 // TODO: uncomment this test once we can run in phantom, which
31 // supports real submit events.
32 /*
@@ -115,4 +114,8 @@ describe('ref swapping', function() {
114 var dog = root.childNodes[0];
115 expect(dog.className).toBe('bigdog');
116 });
117 +
118 + it('should be a valid class', function() {
119 + expect(React.isValidClass(ReactDOM.div)).toBe(true);
120 + });
121 });