From 64f66f59a727ba04eb232c41285a048d3047bef0 Mon Sep 17 00:00:00 2001 From: alisonysy Date: Mon, 6 Apr 2020 20:27:32 +0800 Subject: [PATCH] react.children.map done --- .gitignore | 1 + src/index.js | 24 ++++++++++++++++++--- src/react/ReactChildren.js | 43 +++++++++++++++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 4d29575..9d91014 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ /node_modules /.pnp .pnp.js +package-lock.json # testing /coverage diff --git a/src/index.js b/src/index.js index 8243347..cf2dcfc 100644 --- a/src/index.js +++ b/src/index.js @@ -7,10 +7,13 @@ class Child extends Component { const mappedChildren = React.Children.map( this.props.children, (item, index) => ( - [
{item}
,
{item}
] + [ +
{item}
, +
{item}
+ ] ) ); - console.log(mappedChildren); + console.log('final flattened array: ',mappedChildren); return (
{mappedChildren} @@ -18,6 +21,18 @@ class Child extends Component { ) } } + +function* g(){ + let n=0; + while(n<3){ + yield (
o-{n}
); + n++; + } +} + +let o ={}; +o[Symbol.iterator] = g; + class App extends Component { @@ -34,10 +49,13 @@ class App extends Component { { [
child4
, -
child5
, + [
child5
, +
child5-1
+ ],
child6
] } + {o} ) } diff --git a/src/react/ReactChildren.js b/src/react/ReactChildren.js index bbc07d8..7e22284 100644 --- a/src/react/ReactChildren.js +++ b/src/react/ReactChildren.js @@ -1,6 +1,47 @@ +function _handleKey(key,idx,isIterator,keyFromParent,level){ + // a level starts with '.', different levels are separated by '/' + // if a key is provided, the key should be prefixed with '$', otherwise, use idx as the key without any prefix + // if it is an iterator, i.e. an array or an iterable object, then there's no key and idx is used instead. A ':' will be appended as its children will soon be processed. + const prevLevel = keyFromParent? (keyFromParent.split('/').length - 1) : -1; + const isNewLevel = prevLevel !== level; // if not, level > prevLevel, should append '/' to keyFromParent + keyFromParent = isNewLevel && keyFromParent? (keyFromParent + '/') : keyFromParent ; + let parentKeyPrefix = keyFromParent? keyFromParent : '', + startPrefix = isNewLevel? '.' : ''; + if(key) return parentKeyPrefix + startPrefix + '$' + key; + if(!key && !isIterator) return parentKeyPrefix + startPrefix + idx; + return parentKeyPrefix + startPrefix + idx + ':'; +} + + +function handleKeyForIterator(iterator,keyFromParent,level){ + let n = 0, flattened = []; + for(let k of iterator){ + if(isIterator(k)){ + let preKey = _handleKey(null,n,true,keyFromParent,level); + flattened = flattened.concat(handleKeyForIterator(k,preKey,level)); + }else{ + flattened.push({...k,key:_handleKey(k.key,n,false,keyFromParent,level)}) + }; + n++; + } + return flattened; +} + +function isIterator(el){ + return Object.prototype.toString.call(el) === '[object Array]' || (Object.prototype.toString.call(el) === '[object Object]' && el[Symbol.iterator]); +} + function mapChildren(children, func, context) { //TODO实现此mapChildren方法 - return children; + let immediateChildren = []; + let l = 0; + let newChildren = handleKeyForIterator(children,undefined,l++); + newChildren.map((c,idx)=>{ + let f = func(c,idx); + immediateChildren = immediateChildren.concat(handleKeyForIterator(f,c.key,l)); + }); + // console.log('final flattened array: ',immediateChildren); + return immediateChildren; } export { -- Gitee