src/classic/class/ReactClass.js
/**
 * Mixin helper which handles policy validation and reserved
 * specification keys when building React classses.
 */
Mixin helper which handles policy validation and reserved
specification keys when building React classses.
Mixin helper which handles policy validation and reserved specification keys when building React classses .
function mixSpecIntoComponent(Constructor, spec) {
  if (!spec) {
    return;
  }
  invariant(
    typeof spec !== 'function',
    'ReactClass: You\'re attempting to ' +
    'use a component class as a mixin. Instead, just use a regular object.'
  );
  invariant(
    !ReactElement.isValidElement(spec),
    'ReactClass: You\'re attempting to ' +
    'use a component as a mixin. Instead, just use a regular object.'
  );
  var proto = Constructor.prototype;
  if (spec.hasOwnProperty(MIXINS_KEY)) {
    RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins);
  }
  for (var name in spec) {
    if (!spec.hasOwnProperty(name)) {
      continue;
    }
    if (name === MIXINS_KEY) {
      continue;
    }
    var property = spec[name];
    validateMethodOverride(proto, name);
    if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
      RESERVED_SPEC_KEYS[name](Constructor, property);
    } else {
      var isReactClassMethod =
        ReactClassInterface.hasOwnProperty(name);
      var isAlreadyDefined = proto.hasOwnProperty(name);
      var markedDontBind = property && property.__reactDontBind;
      var isFunction = typeof property === 'function';
      var shouldAutoBind =
        isFunction &&
        !isReactClassMethod &&
        !isAlreadyDefined &&
        !markedDontBind;
      if (shouldAutoBind) {
        if (!proto.__reactAutoBindMap) {
          proto.__reactAutoBindMap = {};
        }
        proto.__reactAutoBindMap[name] = property;
        proto[name] = property;
      } else {
        if (isAlreadyDefined) {
          var specPolicy = ReactClassInterface[name];
          invariant(
            isReactClassMethod && (
              specPolicy === SpecPolicy.DEFINE_MANY_MERGED ||
              specPolicy === SpecPolicy.DEFINE_MANY
            ),
            'ReactClass: Unexpected spec policy %s for key %s ' +
            'when mixing in component specs.',
            specPolicy,
            name
          );
          if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) {
            proto[name] = createMergedResultFunction(proto[name], property);
          } else if (specPolicy === SpecPolicy.DEFINE_MANY) {
            proto[name] = createChainedFunction(proto[name], property);
          }
        } else {
          proto[name] = property;
          if (__DEV__) {
            if (typeof property === 'function' && spec.displayName) {
              proto[name].displayName = spec.displayName + '_' + name;
            }
          }
        }
      }
    }
  }
}
function mixSpecIntoComponent ( Constructor , spec ) { if ( ! spec ) { return ; } invariant ( typeof spec !== 'function' , 'ReactClass: You\'re attempting to ' + 'use a component class as a mixin. Instead, just use a regular object.' ) ; invariant ( ! ReactElement . isValidElement ( spec ) , 'ReactClass: You\'re attempting to ' + 'use a component as a mixin. Instead, just use a regular object.' ) ; var proto = Constructor . prototype ; if ( spec . hasOwnProperty ( MIXINS_KEY ) ) { RESERVED_SPEC_KEYS . mixins ( Constructor , spec . mixins ) ; } for ( var name in spec ) { if ( ! spec . hasOwnProperty ( name ) ) { continue ; } if ( name === MIXINS_KEY ) { continue ; } var property = spec [ name ] ; validateMethodOverride ( proto , name ) ; if ( RESERVED_SPEC_KEYS . hasOwnProperty ( name ) ) { RESERVED_SPEC_KEYS [ name ] ( Constructor , property ) ; } else { var isReactClassMethod = ReactClassInterface . hasOwnProperty ( name ) ; var isAlreadyDefined = proto . hasOwnProperty ( name ) ; var markedDontBind = property && property . __reactDontBind ; var isFunction = typeof property === 'function' ; var shouldAutoBind = isFunction && ! isReactClassMethod && ! isAlreadyDefined && ! markedDontBind ; if ( shouldAutoBind ) { if ( ! proto . __reactAutoBindMap ) { proto . __reactAutoBindMap = { } ; } proto . __reactAutoBindMap [ name ] = property ; proto [ name ] = property ; } else { if ( isAlreadyDefined ) { var specPolicy = ReactClassInterface [ name ] ; invariant ( isReactClassMethod && ( specPolicy === SpecPolicy . DEFINE_MANY_MERGED || specPolicy === SpecPolicy . DEFINE_MANY ) , 'ReactClass: Unexpected spec policy %s for key %s ' + 'when mixing in component specs.' , specPolicy , name ) ; if ( specPolicy === SpecPolicy . DEFINE_MANY_MERGED ) { proto [ name ] = createMergedResultFunction ( proto [ name ] , property ) ; } else if ( specPolicy === SpecPolicy . DEFINE_MANY ) { proto [ name ] = createChainedFunction ( proto [ name ] , property ) ; } } else { proto [ name ] = property ; if ( __DEV__ ) { if ( typeof property === 'function' && spec . displayName ) { proto [ name ] . displayName = spec . displayName + '_' + name ; } } } } } } }
Mixin helper which handles policy validation and reserved
 specification keys when building React classses.
Mixin helper which handles policy validation and reserved specification keys when building React classses .
// By handling mixins before any other properties, we ensure the same // chaining order is applied to methods with DEFINE_MANY policy, whether // mixins are listed before or after these methods in the spec. // We have already handled mixins in a special case above // Setup methods on prototype: // The following member methods should not be automatically bound: // 1. Expected ReactClass methods (in the "interface"). // 2. Overridden methods (that were mixed in). // These cases should already be caught by validateMethodOverride // For methods which are defined more than once, call the existing // methods before calling the new property, merging if appropriate. // Add verbose displayName to the function, which helps when looking // at profiling tools.