Example #1
0
/**
 * Warn if the element doesn't have an explicit key assigned to it.
 * This element 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. Error statuses are cached so a warning
 * will only be shown once.
 *
 * @internal
 * @param {ReactElement} element Element that requires a key.
 * @param {*} parentType element's parent's type.
 */
function validateExplicitKey(element, parentType) {
  if (!element._store || element._store.validated || element.key != null) {
    return;
  }
  element._store.validated = true;

  var memoizer = ownerHasKeyUseWarning.uniqueKey ||
    (ownerHasKeyUseWarning.uniqueKey = {});

  var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);
  if (memoizer[currentComponentErrorInfo]) {
    return;
  }
  memoizer[currentComponentErrorInfo] = true;

  // 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 childOwner = '';
  if (
    element && element._owner && element._owner !== ReactCurrentOwner.current
  ) {
    // Give the component that originally created this child.
    childOwner = ` It was passed a child from ${getComponentName(element._owner)}.`;
  }

  warning(
    false,
    'Each child in an array or iterator should have a unique "key" prop.' +
      '%s%s See https://fb.me/react-warning-keys for more information.%s',
    currentComponentErrorInfo,
    childOwner,
    getCurrentStackAddendum(element),
  );
}
 ReactDebugCurrentFrame.getStackAddendum = function(): string | null {
   let stack = null;
   const current = ReactDebugCurrentFrame.current;
   const element = ReactDebugCurrentFrame.element;
   if (current !== null) {
     if (typeof current === 'number') {
       // DebugID from Stack.
       const debugID = current;
       stack = getStackAddendumByID(debugID);
     } else if (typeof current.tag === 'number') {
       // This is a Fiber.
       // The stack will only be correct if this is a work in progress
       // version and we're calling it during reconciliation.
       const workInProgress = current;
       stack = getStackAddendumByWorkInProgressFiber(workInProgress);
     }
   } else if (element !== null) {
     stack = getCurrentStackAddendum(element);
   }
   return stack;
 };
  createElement: function(type, props, children) {
    var validType =
      typeof type === 'string' ||
      typeof type === 'function';
    // We warn in this case but don't throw. We expect the element creation to
    // succeed and there will likely be errors in render.
    if (!validType) {
      var info = '';
      if (
        type === undefined ||
        typeof type === 'object' &&
        type !== null &&
        Object.keys(type).length === 0
      ) {
        info +=
          ' You likely forgot to export your component from the file ' +
          'it\'s defined in.';
      }

      var sourceInfo = getSourceInfoErrorAddendum(props);
      if (sourceInfo) {
        info += sourceInfo;
      } else {
        info += getDeclarationErrorAddendum();
      }

      info += getCurrentStackAddendum();

      warning(
        false,
        'React.createElement: type is invalid -- expected a string (for ' +
        'built-in components) or a class/function (for composite ' +
        'components) but got: %s.%s',
        type == null ? type : typeof type,
        info,
      );
    }

    var element = ReactElement.createElement.apply(this, arguments);

    // The result can be nullish if a mock or a custom function is used.
    // TODO: Drop this when these are no longer allowed as the type argument.
    if (element == null) {
      return element;
    }

    if (__DEV__) {
      ReactDebugCurrentFrame.element = element;
    }

    // Skip key warning if the type isn't valid since our key validation logic
    // doesn't expect a non-string/function type and can throw confusing errors.
    // We don't want exception behavior to differ between dev and prod.
    // (Rendering will throw with a helpful message and as soon as the type is
    // fixed, the key warnings will appear.)
    if (validType) {
      for (var i = 2; i < arguments.length; i++) {
        validateChildKeys(arguments[i], type);
      }
    }

    validatePropTypes(element);

    if (__DEV__) {
      ReactDebugCurrentFrame.element = null;
    }

    return element;
  },