如何在 React 中使用 map 输出嵌套对象的内容?

How to output content of a nested object using map in React?

我有一个 json 如下所示

const assessmentData = [
    {
        "Sit1": [
            {
                "rule": "Rule1",
                "type": "High"
            }
        ]
    },
    
    {
        "Sit2": [
            {
                "rule": "Rule6",
                "type": "Low"
            }
        ]
    },
    
    {
        "Sit3": [
            {
                "rule": "Rule3",
                "type": "High"
            }
        ]
    }
]

现在我想渲染一些包含上述信息的 html。通常在香草 HTML,这就是我所做的

let content = ""

for(let i=0; i < assessmentData.length; i++) {
    for (const [key, value] of Object.entries(assessmentData[i])) {
        content += `<h2>${key}<h2>`
        for (const [subkey, subvalue] of Object.entries(value)) {
            const rule = subvalue["rule"]
            content += `<h3>${rule}</h3>`
        }
    }   
}

所以最终输出看起来像

<h2>Sit1<h2><h3>Rule1</h3><h2>Sit2<h2><h3>Rule1</h3><h2>Sit3<h2><h3>Rule1</h3>

但我无法使用 map 功能做同样的事情。所以我在 react 中的代码看起来像

const CreateTemplate = (assessmentData) => {

     const content = assessmentData.map((item, idx) => {
        Object.keys(item).map((subitem, subindex) => {
            <h2>{subitem}</h2>
            Object.keys(item[subitem]).map((subitem2, subindex2) => {
                <h3>{item[subitem][subitem2]["rule"]}</h3>
            })
            
        })
               
     
      });


     return (
        <div>Content</div>
        {content}
     )
}

export default CreateTemplate

不输出content部分。我做错了什么?

您应该 return 来自地图回调的值。 * 您还可以使用 Object.entries 映射键值对数组。由于该值已经是一个数组,因此您不需要使用键 A.K.A。数组索引,您可以简单地映射数组值。

const content = assessmentData.map((item, idx) => {
  return Object.entries(item).map(([key, value], subindex) => {
    return (
      <React.Fragment key={subindex}>
        <h2>{key}</h2>
        {value.map((subitem2, subindex2) => {
          return <h3 key={subindex2}>{subitem2.rule}</h3>
        })}
      </React.Fragment>
    );
  });
});

* 我尝试匹配所有括号,但希望您的 IDE 比我在纯文本编辑器中做得更好

或者使用隐式箭头函数returns:

const content = assessmentData.map((item, idx) =>
  Object.entries(item).map(([key, value], subindex) => (
    <React.Fragment key={subindex}>
      <h2>{key}</h2>
      {value.map((subitem2, subindex2) => (
        <h3 key={subindex2}>{subitem2.rule}</h3>
      ))}
    </React.Fragment>
  ))
);

此外,作为一般问题的解决方案,您可以提出递归遍历对象或具有可变深度的数组,也许对某些人有用。

window.Fragment = React.Fragment
const assessmentData = [
    {
        "Sit1": [
            {
                "rule": "Rule1",
                "type": "High"
            }
        ]
    },
    {
        "Sit2": [
            {
                "rule": "Rule6",
                "type": "Low"
            }
        ]
    },
    {
        "another example:" : [
           {items: [1, 2]}, {other: [4, 5, 6]}
         ]
    }
]

const getObject = (obj, level) => {
  return Object.entries(obj).map(([key, val], i) => {
    return <Fragment key={`key${i}`}>{getTree(key, level + 1)}{getTree(val, level + 2)}</Fragment>
  })
}

const getArray = (arr, level) => {
  return arr.map((e, i) => {
    return <Fragment key={`key${i}`}>{getTree(e, level + 1)}</Fragment> 
  })
}

const getTree = (data, level=0) => {
  if (data instanceof Array) {
     return getArray(data, level)
  } else if (data instanceof Object) {
     return getObject(data, level) 
  }
  return <p style={{fontSize:`${20 - level}px`, paddingLeft: `${level}em`}}>{data}</p>      
}

const App = () => {
  return (
    <div>
      { getTree(assessmentData) }
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
* {
  margin: 0;
  padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>