1. export function cloneElement(element, config, children) {
    2. if (element === null || element === undefined) {
    3. throw new Error(
    4. `React.cloneElement(...): The argument must be a React element, but you passed ${element}.`,
    5. );
    6. }
    7. let propName;
    8. // Original props are copied
    9. const props = Object.assign({}, element.props);
    10. // Reserved names are extracted
    11. let key = element.key;
    12. let ref = element.ref;
    13. // Self is preserved since the owner is preserved.
    14. const self = element._self;
    15. // Source is preserved since cloneElement is unlikely to be targeted by a
    16. // transpiler, and the original source is probably a better indicator of the
    17. // true owner.
    18. const source = element._source;
    19. // Owner will be preserved, unless ref is overridden
    20. let owner = element._owner;
    21. if (config != null) {
    22. if (hasValidRef(config)) {
    23. // Silently steal the ref from the parent.
    24. ref = config.ref;
    25. owner = ReactCurrentOwner.current;
    26. }
    27. if (hasValidKey(config)) {
    28. key = '' + config.key;
    29. }
    30. // Remaining properties override existing props
    31. let defaultProps;
    32. if (element.type && element.type.defaultProps) {
    33. defaultProps = element.type.defaultProps;
    34. }
    35. for (propName in config) {
    36. if (
    37. hasOwnProperty.call(config, propName) &&
    38. !RESERVED_PROPS.hasOwnProperty(propName)
    39. ) {
    40. if (config[propName] === undefined && defaultProps !== undefined) {
    41. // Resolve default props
    42. props[propName] = defaultProps[propName];
    43. } else {
    44. props[propName] = config[propName];
    45. }
    46. }
    47. }
    48. }
    49. // Children can be more than one argument, and those are transferred onto
    50. // the newly allocated props object.
    51. const childrenLength = arguments.length - 2;
    52. if (childrenLength === 1) {
    53. props.children = children;
    54. } else if (childrenLength > 1) {
    55. const childArray = Array(childrenLength);
    56. for (let i = 0; i < childrenLength; i++) {
    57. childArray[i] = arguments[i + 2];
    58. }
    59. props.children = childArray;
    60. }
    61. return ReactElement(element.type, key, ref, self, source, owner, props);
    62. }