diff --git a/.gitignore b/.gitignore
index 4d29575de80483b005c29bfcac5061cd2f45313e..9d9101486e2a3faf49f32023b0ac925ebf693023 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 82433470761e01cd6adcfe1e06535ee1819bc83b..cf2dcfc1ec200ed1735ca1ed084f0fd36f89a0ab 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) => (
- [
{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 bbc07d81edaad3705a3dca0942e1cbc01bff2624..7e22284626e5dc5c9ad49f666b0a46362347ca0d 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 {