forked from facebook/react
-
Notifications
You must be signed in to change notification settings - Fork 0
/
flattenChildren.js
80 lines (74 loc) · 2.35 KB
/
flattenChildren.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/**
* 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.
*
* @providesModule flattenChildren
* @flow
*/
'use strict';
var ReactComponentTreeDevtool = require('ReactComponentTreeDevtool');
var KeyEscapeUtils = require('KeyEscapeUtils');
var traverseAllChildren = require('traverseAllChildren');
var warning = require('warning');
/**
* @param {function} traverseContext Context passed through traversal.
* @param {?ReactComponent} child React child component.
* @param {!string} name String name of key path to child.
* @param {number=} selfDebugID Optional debugID of the current internal instance.
*/
function flattenSingleChildIntoContext(
traverseContext: mixed,
child: ReactElement<any>,
name: string,
selfDebugID: number
): void {
// We found a component instance.
if (traverseContext && typeof traverseContext === 'object') {
const result = traverseContext;
const keyUnique = (result[name] === undefined);
if (__DEV__) {
warning(
keyUnique,
'flattenChildren(...): Encountered two children with the same key, ' +
'`%s`. Child keys must be unique; when two children share a key, only ' +
'the first child will be used.%s',
KeyEscapeUtils.unescape(name),
ReactComponentTreeDevtool.getStackAddendumByID(selfDebugID)
);
}
if (keyUnique && child != null) {
result[name] = child;
}
}
}
/**
* Flattens children that are typically specified as `props.children`. Any null
* children will not be included in the resulting object.
* @return {!object} flattened children keyed by name.
*/
function flattenChildren(children: ReactElement<any>, selfDebugID: number): ?{ [name: string]: ReactElement<any> } {
if (children == null) {
return children;
}
var result = {};
if (__DEV__) {
traverseAllChildren(
children,
(traverseContext, child, name) => flattenSingleChildIntoContext(
traverseContext,
child,
name,
selfDebugID
),
result
);
} else {
traverseAllChildren(children, flattenSingleChildIntoContext, result);
}
return result;
}
module.exports = flattenChildren;