React映射多个数组

时间:2017-06-22 19:17:03

标签: javascript arrays reactjs

对不起有任何困惑。简单地说,我想用无序列表制作几个标题。

<h3>level_3 key title</h3>
<ul>
  <li>level_4 value</li>
  <li>level_4 value</li>
</ul>

<h3> another level_3 key title</h3>
<ul>
  <li>level_4 value</li>
  <li>level_4 value</li>
</ul> 

难以将问题表达为问题。基本上很难尝试解析一些JSON并正确显示数据。我想要做的是将level_3.x 显示在下面作为顶级列表项,将嵌套level_4.x显示为嵌套列表项。要清楚使用React

示例:

  • 来自level_3.1的密钥
    • 来自level_4.1
    • 的字符串
    • 来自level_4.2
    • 的字符串

重复每个level_3.x对象

示例数据

"level_1":{
  "level_2.1":{
    "level_3.1":{
     "level_4.1":["string","string","string"],
     "level_4.2":["string","string","string"]
    }
    "level_3.2":{
     "level_4.1":["string","string","string"],
     "level_4.2":["string","string","string"]
    }
  }
  "level_2.2":{
     "level_3.1":{
       ... Same as above
    }
     "level_3.2":{
       ... Same as above
    }
  }
}

我所做的事情,因为根据我的理解,你只能映射一个数组,试着通过level_3.x并将它们推送到数组。我可以映射它并按预期显示项目。

父组件

render(){
  return( <Child heading="A" data={resource.data} /> )
}

子组件

render(){
  let groupObj;
  let groupArray;
  let subListItems;

  if('value' in this.props.data){
    var i;
    for(i = 0; i < Object.keys(groupObj).length; i++){
      groupArray.push(Object.keys(groupObj)[i] + "," + Object.values(groupObj)[i]) 
// Have removed the Object.values because I was trying to make everything flat and pull out the first item. Leaving it in because that was my original direction in the case it was actually the right way to go
    }
  }
  listItems = groupArray.map((item, index)=>(<li key={index}>{item}</li>));

  return({listItems})
}

到目前为止,我可以制作:

  • level_3.1
  • level_3.2

console log > [level_3.1,level_3.2]

哪个好,哪一半。现在事情发生了,我似乎无法弄清楚如何让level_4.x元素呈现。

我尝试在上一个内部编写另一个map函数:

listItems = groupArray.map((item, index) => (
   <li key={index}>
     {item}
     <ul>
       {subListItems = groupObj.item.map((subItem, index) => ( 
         <li key={index+1}>{subItem}</li>
       ))};
     </ul>
   </li>
 ));

这将返回未定义错误的映射,但是如果item被替换为密钥,它将起作用。 groupObj.level_4.1.map()这将返回level_4.1值:

  • level_3.1
    • level_4.1 value
    • level_4.1 value&lt;&lt;无法映射level_4.2并使用父地图函数中的item将返回undefined

所以要么完全错误,要么错过了将动态值传递到groupObj.[needs to be dynamic based on parent].map()

的方法

请注意,请注意,使用index作为键值是反模式只是为了让它能够正常工作。

更新

感觉这是90%,但最后一个问题。考虑到这两个答案,我最容易实现并理解我此时输入的内容如下:

render(){

  let listItems;
  let name = this.props.heading

  if('level_2' in this.props.data){

    let data = this.props.data.level_2[name];
    console.log('ok we can get to work', data); // <<< Good

    listItems = Object.keys(data).map((propKey) => (
      <ul key={propKey}>
       {propKey} // <<< Good
       {console.log('PROP KEY', propKey)} // <<< Good
         {data[propKey].map((childPropKey) =>{
           <li key={childPropKey}>
             {childPropKey} // <<<<<< PROBLEM, This returns nothing in the DOM
             {console.log(childPropKey)} // <<< Good
           </li>
         })}
     </ul>
   ));

return(<div>{listItems}</div>)
}

所以我能够console.log(childPropKey)并返回预期的结果。但只是试图返回{childPropKey}没有返回

使用ES5

listItems = Object.keys(data).map(function(propKey){
    return <ul key={propKey}>
      {propKey}
        {data[propKey].map(function(childPropKey){
          return <li key={childPropKey}>
            {childPropKey}
          </li>
        })}
    </ul>
  });

使用ES6

listItems = Object.keys(data).map((propKey) => (
  <ul key={propKey}>
    {propKey}
    {data[propKey].map((childPropKey) =>(
      <li key={childPropKey}>
        {childPropKey}                 
      </li>
     ))}
  </ul>
));

2 个答案:

答案 0 :(得分:3)

不要试图将对象转换为数组,只需将其剪切并直接通过Object.keys数组循环。

render () (
  <ul>
    {Object.keys(this.props.data).map((propKey) => {
      <li key={propKey}>
        {this.props.data[propKey]}

        <ul>            
          {Object.keys(this.props.data[propKey]).map((childPropKey) => {
            <li key={childPropKey}>
              {this.props.data[propKey][childPropKey]}
            </li>
          })}
        </ul>
      </li>
    })}
  </ul>
);

我已经对您的数据结构做了一些假设,所以希望您可以将其转换为您的实现。

答案 1 :(得分:3)

您应该考虑这种问题的递归,因为它非常适合树遍历。

大多数人都不知道您可以将React组件视为函数并以递归方式使用它们。为了呈现不同类型的节点,您可以使用三元运算符,switch语句或其他控制流机制。

要迭代Object,您可以使用Object.entries获取键值对列表,然后您可以使用常规map进行处理。

请参阅以下示例:

const isLeaf = data => typeof data === 'string'
const isArray = data => Array.isArray(data)

const Tree = ({ data }) =>
  // render a leaf - just a string
  isLeaf(data) ? <li>{data}</li> : 

  // render an array
  isArray(data) ? 
  <ul>
    {data.map(x => <Tree data={x} />)}
  </ul> : 

  // render a tree (an object)
  <ol>
  {
    Object.entries(data).map(([key, value]) =>
      <li>
        <h1>{key}</h1>
        <Tree data={value} />
      </li>
    )
  }
  </ol>

const data = {
  "level_1":{
    "level_2.1":{
      "level_3.1":{
       "level_4.1":["a","b","c"],
       "level_4.2":["string","string","string"]
      },
      "level_3.2":{
       "level_4.1":["string","e","string"],
       "level_4.2":["d","string","f"]
      }
    },
    "level_2.2":{
      "level_3.1":{
       "level_4.1":["string","string","string"],
       "level_4.2":["string","string","string"]
      },
      "level_3.2":{
       "level_4.1":["string","string","string"],
       "level_4.2":["string","string","string"]
      }
    }
  }
}

ReactDOM.render(
  <Tree data={data} />,
  document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>