From df2ac682181ba4fa56cbbf1254db33ae6a03c280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=A6=E7=A3=8A?= Date: Wed, 8 Apr 2020 09:51:14 +0800 Subject: [PATCH] #9# finish map --- src/react/ReactChildren.js | 85 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/src/react/ReactChildren.js b/src/react/ReactChildren.js index bbc07d8..0c1be7c 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 +}; -- Gitee