checkReactTypeSpec 触发props、context、childContext的校验函数。由“react-dom"包下的ReactCompositeComponent模块创建组件实例时调用,校验context、childContext;或者由"react"包下的ReactElementValidator模块调用创建ReactElement时调用,校验props。
/** * Copyright 2013-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ 'use strict'; var _prodInvariant = require('./reactProdInvariant'); // 用于区分校验数据类型prop、context、childContext var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames'); // 用于判断是否内部调用props校验函数 var ReactPropTypesSecret = require('./ReactPropTypesSecret'); // invariant(condition,format,a,b,c,d,e,f) condition为否值,替换format中的"%s",并throw error报错 var invariant = require('fbjs/lib/invariant'); // warning(condition,format) condition为否值,替换format中的"%s",并console.error警告 var warning = require('fbjs/lib/warning'); var ReactComponentTreeHook; if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'test') { ReactComponentTreeHook = require('./ReactComponentTreeHook'); } var loggedTypeFailures = {}; // “react-dom"包下的ReactCompositeComponent、"react"包下的ReactElementValidator模块调用 // 用于创建自定义组件实例时校验context、childContext属性,或创建ReactElement时校验props属性 // 参数typeSpecs为自定义组件的PropTypes静态属性、或contextTypes实例属性、或childContextTypes实例属性 // 参数values为ReactElement的props属性 // 参数location为字符串"prop"、"context"、"childContext",以区分校验数据类型 // 参数componentName为自定义组件的displayName // 参数element为ReactElement function checkReactTypeSpec(typeSpecs, values, location, componentName, element, debugID) { for (var typeSpecName in typeSpecs) { if (typeSpecs.hasOwnProperty(typeSpecName)) { var error; try { // PropTypes、contextTypes、childContextTypes设定属性的校验函数不是函数时,报错 !(typeof typeSpecs[typeSpecName] === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, ' + 'usually from React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : _prodInvariant('84', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : void 0; // 调用设定的校验函数作校验 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); } catch (ex) { error = ex; } // 校验函数最终返回值须为否值或error对象 // function(propValue,key){}}需返回否值或error对象,否则警告 process.env.NODE_ENV !== 'production' ? warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName, typeof error) : void 0; // 替代警告文案 if (error instanceof Error && !(error.message in loggedTypeFailures)) { loggedTypeFailures[error.message] = true; var componentStackInfo = ''; if (process.env.NODE_ENV !== 'production') { if (!ReactComponentTreeHook) { ReactComponentTreeHook = require('./ReactComponentTreeHook'); } if (debugID !== null) { componentStackInfo = ReactComponentTreeHook.getStackAddendumByID(debugID); } else if (element !== null) { componentStackInfo = ReactComponentTreeHook.getCurrentStackAddendum(element); } } process.env.NODE_ENV !== 'production' ? warning(false, 'Failed %s type: %s%s', location, error.message, componentStackInfo) : void 0; } } } } module.exports = checkReactTypeSpec;