function numberValidator (props, propName, componentName) { if (isNaN(Number(props[propName]))) { return new Error( [ componentName, 'requires that', '"' + propName + '"', 'be a Number.' ].join(' ')); } }; function requireableProp(testFn) { function testProp(props, propName, componentName) { var propVal = props[propName]; var propIsEmpty = [undefined,null,''].indexOf(propVal) > -1; var isRequired = arguments.length > 3 && arguments[arguments.length-1] === true; var error; if (isRequired === true && propIsEmpty) { error = new Error([ componentName, 'requires that', '"' + propName + '"', 'be populated' ].join(' ')); } else if (!(!isRequired && propIsEmpty)) { error = testFn(props, propName, componentName); } if (error !== undefined) { //only posting output to show the errors generated var outputEl = document.getElementById('output'); var errorDiv = outputEl.querySelector('#'+propName); if (errorDiv === null) { errorDiv = document.createElement('DIV'); errorDiv.id = propName; outputEl.appendChild(errorDiv); } errorDiv.innerText = error.message; return error; } } testProp.isRequired = function isRequiredProp() { Array.prototype.push.call(arguments, true); return testProp.apply(null, arguments); }; return testProp; } var requireableNumber = requireableProp(numberValidator); var testComponent = React.createClass({ displayName: 'Test Component', propTypes: { number: requireableNumber, //NOT Required, valid if empty requiredNumber: requireableNumber.isRequired //REQUIRED }, render: function doRender() { return React.DOM.div(null, [ 'number = ' + this.props.number, React.DOM.br(), 'requiredNumber = ' + this.props.requiredNumber ]); } }); var numberOne, numberTwo = 5; //numberOne = 'Not-A-Number'; //(un)comment this to test the non-required number validator numberTwo = undefined; //(un)comment this to test the required number validator React.render(React.createElement(testComponent, { number: numberOne, requiredNumber: numberTwo }, null), document.getElementById('component'));
<main> <section class="component-output"> <h3>Component Output</h3> <div id="component"></div> </section> <section class="validator-output"> <h3>Validator Output</h3> <div id="output"></div> </section> </main>