diff --git a/src/react/ReactChildren.js b/src/react/ReactChildren.js index bbc07d81edaad3705a3dca0942e1cbc01bff2624..0c1be7c6397c217c375a0fc7e33c8fd29628f44e 100644 --- a/src/react/ReactChildren.js +++ b/src/react/ReactChildren.js @@ -1,8 +1,87 @@ function mapChildren(children, func, context) { - //TODO实现此mapChildren方法 - return children; + if (isInvalid(children)) { + return []; + } + let result = []; + traverseChildren(children, function (child, index, key, originalKey) { + let mapped = fn.call(context, child, index); + if (!isInvalid(mapped)) { + if (isValidElement(mapped)) { + var newKey = key; + if (!isNullOrUndef(mapped.key) && mapped.key !== originalKey) { + newKey = `${mapped.key}/${key}`; + } + mapped = cloneElement(mapped, { key: newKey }); + } + result.push(mapped); + } + }) + + return result; +} + +function traverseChildren( + children, + callback, +) { + if (isNullOrUndef(children)) { + return 0; + } + + var key: string | undefined, mangledKey: string; + if (!Array.isArray(children)) { + // 单个孩子节点 + if (isObject(children)) { + key = children.key as string; + } + mangledKey = isNullOrUndef(key) ? '.0' :`.$${key}`; + callback(children, 0, mangledKey, key); + return 1; + } else if (children.length) { + // 多个节点,通过 stack 进行非递归的数组展开 + var count = 0; + var objStack = [children]; + var idxStack = [0]; + var keyPrefixStack = ['.']; + var objIndex = 0; + while (objIndex >= 0) { + var currentArray = objStack[objIndex]; + var currentIdx = idxStack[objIndex]; + var obj = currentArray[idxStack[objIndex]++]; + var keyPrefix = keyPrefixStack[objIndex]; + if (currentIdx + 1 >= currentArray.length) { + objStack.pop(); + idxStack.pop(); + keyPrefixStack.pop(); + objIndex--; + } + if (Array.isArray(obj)) { + if (obj.length) { + objStack.push(obj); + idxStack.push(0); + keyPrefixStack.push(`${keyPrefix}${currentIdx}:`) + objIndex++; + } + } else { + if (isInvalid(obj)) { + obj = null; + key = undefined; + } else if (isObject(obj)) { + key = obj.key as string; + } else { + key = undefined; + } + mangledKey = `${keyPrefix}${isNullOrUndef(key) ? currentIdx : ('$' + key)}` + callback(obj, count, mangledKey, key); + count++; + } + } + return count; + } + // 空数组 + return 0; } export { mapChildren as map, -}; \ No newline at end of file +};