Skip to content

Commit 1aa9cc6

Browse files
Guangqiang Dongzpao
authored andcommitted
add count() method to ReactChildren
added ReactChildren.count() to count the number of children, and a test case.
1 parent 5b17e75 commit 1aa9cc6

File tree

3 files changed

+85
-2
lines changed

3 files changed

+85
-2
lines changed

src/utils/ReactChildren.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,25 @@ function mapChildren(children, func, context) {
129129
return mapResult;
130130
}
131131

132+
/**
133+
* Count the number of children that are typically specified as
134+
* `props.children`.
135+
*/
136+
137+
function forEachSingleChildDummy(traverseContext, child, name, i) {
138+
return null;
139+
}
140+
141+
function countChildren(children, context) {
142+
var numberOfChildren = traverseAllChildren(children, forEachSingleChildDummy,
143+
null);
144+
return numberOfChildren;
145+
}
146+
132147
var ReactChildren = {
133148
forEach: forEachChildren,
134-
map: mapChildren
149+
map: mapChildren,
150+
count: countChildren
135151
};
136152

137153
module.exports = ReactChildren;

src/utils/__tests__/ReactChildren-test.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,4 +335,67 @@ describe('ReactChildren', function() {
335335
expect(console.warn.calls.length).toEqual(1);
336336
expect(mapped).toEqual({'.$something': zero});
337337
});
338+
339+
it('should return 0 for null children', function() {
340+
var numberOfChildren = ReactChildren.count(null);
341+
expect(numberOfChildren).toBe(0);
342+
});
343+
344+
it('should return 0 for undefined children', function() {
345+
var numberOfChildren = ReactChildren.count(undefined);
346+
expect(numberOfChildren).toBe(0);
347+
});
348+
349+
it('should return 1 for single child', function() {
350+
var simpleKid = <span key="simple" />;
351+
var instance = <div>{simpleKid}</div>;
352+
var numberOfChildren = ReactChildren.count(instance.props.children);
353+
expect(numberOfChildren).toBe(1);
354+
});
355+
356+
it('should count the number of children in flat structure', function() {
357+
var zero = <div key="keyZero" />;
358+
var one = null;
359+
var two = <div key="keyTwo" />;
360+
var three = null;
361+
var four = <div key="keyFour" />;
362+
363+
var instance = (
364+
<div>
365+
{zero}
366+
{one}
367+
{two}
368+
{three}
369+
{four}
370+
</div>
371+
);
372+
var numberOfChildren = ReactChildren.count(instance.props.children);
373+
expect(numberOfChildren).toBe(5);
374+
});
375+
376+
it('should count the number of children in nested structure', function() {
377+
var zero = <div key="keyZero" />;
378+
var one = null;
379+
var two = <div key="keyTwo" />;
380+
var three = null;
381+
var four = <div key="keyFour" />;
382+
var five = <div key="keyFiveInner" />;
383+
// five is placed into a JS object with a key that is joined to the
384+
// component key attribute.
385+
// Precedence is as follows:
386+
// 1. If grouped in an Object, the object key combined with `key` prop
387+
// 2. If grouped in an Array, the `key` prop, falling back to array index
388+
389+
var instance = (
390+
<div>{
391+
[{
392+
firstHalfKey: [zero, one, two],
393+
secondHalfKey: [three, four],
394+
keyFive: five
395+
}]
396+
}</div>
397+
);
398+
var numberOfChildren = ReactChildren.count(instance.props.children);
399+
expect(numberOfChildren).toBe(6);
400+
});
338401
});

src/utils/traverseAllChildren.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,14 @@ var traverseAllChildrenImpl =
180180
* @param {?*} children Children tree object.
181181
* @param {!function} callback To invoke upon traversing each child.
182182
* @param {?*} traverseContext Context for traversal.
183+
* @return {!number} The number of children in this subtree.
183184
*/
184185
function traverseAllChildren(children, callback, traverseContext) {
185186
if (children !== null && children !== undefined) {
186-
traverseAllChildrenImpl(children, '', 0, callback, traverseContext);
187+
return traverseAllChildrenImpl(children, '', 0, callback, traverseContext);
188+
}
189+
else {
190+
return 0;
187191
}
188192
}
189193

0 commit comments

Comments
 (0)