diff --git a/src/react/ReactChildren.js b/src/react/ReactChildren.js index bbc07d81edaad3705a3dca0942e1cbc01bff2624..068ee1d23caa949bd26852a7635b536e261f588a 100644 --- a/src/react/ReactChildren.js +++ b/src/react/ReactChildren.js @@ -1,8 +1,66 @@ -function mapChildren(children, func, context) { - //TODO实现此mapChildren方法 +import { REACT_ELEMENT_TYPE } from '../shared/ReactSymbols'; + +function mapIntoArray(children, array, callback) { + const type = typeof children; + + if (type === 'undefined' || type === 'boolean') { + children = null; + } + + let invokeCallback = false; + + if (children === null) { + invokeCallback = true; + } else { + switch (type) { + case 'string': + case 'number': + invokeCallback = true; + break; + case 'object': + switch (children.$$typeof) { + case REACT_ELEMENT_TYPE: + invokeCallback = true; + } + } + } + if (invokeCallback) { + const child = children; + let mappedChild = callback(child); + if (Array.isArray(mappedChild)) { + mappedChild.map(child => mapIntoArray(child, array, c => c)) + } else { + array.push(child) + } + } + if (Array.isArray(children)) { + for (let i = 0; i < children.length; i++) { + let child = children[i] + mapIntoArray( + child, + array, + callback, + ) + } + } +} + +function mapChildren( + children, + func, + context, +) { + if (children == null) { return children; + } + const result = []; + let count = 0; + mapIntoArray(children, result, function(child) { + return func.call(context, child, count++); + }); + return result; } export { - mapChildren as map, -}; \ No newline at end of file + mapChildren as map, +};