functiontraverseAllChildrenImpl( children, nameSoFar, callback, traverseContext, ) { var type = typeof children;
if (type === 'undefined' || type === 'boolean') { // All of the above are perceived as null. children = null; }
if ( children === null || type === 'string' || type === 'number' || // The following is inlined from ReactElement. This means we can optimize // some checks. React Fiber also inlines this logic for similar purposes. (type === 'object' && children.$$typeof === REACT_ELEMENT_TYPE) ) { callback( traverseContext, children, // If it's the only child, treat the name as if it was wrapped in an array // so that it's consistent if the number of children grows. nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar, ); return1; }
接收四个参数,首先判断 children 参数的 type ,不合法都认为 children 是 null. 紧接着的一堆判断,就是说当 children 是单个合法 React 元素的时候,执行 callback 函数,并返回 1,因为后面会递归的调用当前这个函数,所以这里也是递归调用的出口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
var child; var nextName; var subtreeCount = 0; // Count of children found in the current subtree. var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR;
if (Array.isArray(children)) { for (var i = 0; i < children.length; i++) { child = children[i]; nextName = nextNamePrefix + getComponentKey(child, i); subtreeCount += traverseAllChildrenImpl( child, nextName, callback, traverseContext, ); } } else {
} else { var iteratorFn = (ITERATOR_SYMBOL && children[ITERATOR_SYMBOL]) || children[FAUX_ITERATOR_SYMBOL]; if (typeof iteratorFn === 'function') { if (__DEV__) { // Warn about using Maps as children if (iteratorFn === children.entries) { warning( didWarnAboutMaps, 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.%s', getStackAddendum(), ); didWarnAboutMaps = true; } }
var iterator = iteratorFn.call(children); var step; var ii = 0; while (!(step = iterator.next()).done) { child = step.value; nextName = nextNamePrefix + getComponentKey(child, ii++); subtreeCount += traverseAllChildrenImpl( child, nextName, callback, traverseContext, ); } } elseif (type === 'object') { var addendum = ''; if (__DEV__) { addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getStackAddendum(); } var childrenString = '' + children; invariant( false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum, ); } }
var mappedChild = func.call(context, child, bookKeeping.count++); if (Array.isArray(mappedChild)) { mapIntoWithKeyPrefixInternal( mappedChild, result, childKey, emptyFunction.thatReturnsArgument ); } elseif (mappedChild != null) { if (ReactElement.isValidElement(mappedChild)) { mappedChild = ReactElement.cloneAndReplaceKey( mappedChild, // Keep both the (mapped) and old keys if they differ, just as // traverseAllChildren used to do for objects as children keyPrefix + (mappedChild.key && (!child || child.key !== mappedChild.key) ? escapeUserProvidedKey(mappedChild.key) + "/" : "") + childKey ); } result.push(mappedChild); } }