【问题标题】:How to output content of a nested object using map in React?如何在 React 中使用 map 输出嵌套对象的内容?
【发布时间】:2022-01-22 14:41:07
【问题描述】:

我有一个如下所示的 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 部分。我做错了什么?

【问题讨论】:

    标签: reactjs react-hooks react-templates


    【解决方案1】:

    您应该从地图回调中返回值。 * 您还可以使用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 比我在纯文本编辑器中做得更好

    或者使用隐式箭头函数返回:

    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>
      ))
    );
    

    【讨论】:

    • 感谢您强调这一点。所以诀窍是每个循环,我需要返回输出对吗?
    • @SouvikRay 肯定的。将数组从一组值映射到另一组时,您需要返回要映射到的值。这包括您要映射到的值是否也是需要映射到其他值的数组。
    【解决方案2】:

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

    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>

    【讨论】:

      猜你喜欢
      • 2019-09-15
      • 1970-01-01
      • 1970-01-01
      • 2021-12-30
      • 2021-06-25
      • 2021-04-24
      • 2020-05-24
      • 1970-01-01
      • 2020-03-25
      相关资源
      最近更新 更多