【问题标题】:Double for loops in React using .map在 React 中使用 .map 进行双重 for 循环
【发布时间】:2019-02-12 06:36:51
【问题描述】:

我正在尝试在 React 中为我创建的一些 JSON 内容创建一个双 for 循环:

"students": [
        {
          "name": "person",
          "photoURL": "https://via.placeholder.com/100x100",
          "subjects":[
            "physics",
            "math",
            "english"
          ],
          "nextClass": "August 29th, 2018"
        },
        {
          "name": "human",
          "photoURL": "https://via.placeholder.com/100x100",
          "subjects":[
            "chemistry",
            "math",
            "french"
          ],
          "nextClass": "August 27th, 2018"
        }]

在我的 JSX 中,我尝试遍历学生对象,然后再次遍历所有科目以创建一个无序列表:

render(){

    return(
          <div id="display-students">
            {this.props.students.map((x,i) =>{
              return (
                <div className="student" key={i}>
                  <h2>{x.name}</h2>
                  <img src={x.photoURL} alt="profile"/>
                  <h3>Subjects: </h3>
                  <ul>
                      {x.subjects.map((y) => <li>{y}</li>)}
                  </ul>
                </div>  
              )
            })} 
          </div>
        )
   }

但是,这个错误出现在浏览器中:

当我尝试渲染时

<ul>
    {x.subjects}
</ul>

我看到数组中的所有内容都混合成一个字符串:

关于为什么会发生这种情况的任何指示? 我们甚至可以在 JSX 中使用双循环吗?

提前致谢!

【问题讨论】:

  • 双循环很好。我已经获取了您的确切代码和数据集,并且能够很好地呈现ul。这是整个数据集吗?
  • 如果您的内容全部混合在一个字符串中,这可能是因为您尚未解析 JSON 数据。字符串到底在哪里? X 是字符串吗?如果是你应该做 JSON.parse(x),但是它不应该首先是一个字符串,所以无论为你提供道具是给你一个字符串数组而不是 JSON 对象数组跨度>
  • 我不确定这是否值得回答,因为似乎解决方案可能在您的 api 中。但我认为@kyle 可能会有所作为。虽然,如果你想返回 json,我通常在后端使用 express 时使用 res.json(jsonDataHere)。我的第一个想法是:也许其中一些学生没有任何科目(subjects 不存在)。但其次,您可以使用console.log(typeof x.subjects) 对其进行调试
  • 没有更多信息,我没有想法,特别是因为你的例子在这里工作得很好。我猜这与您如何模拟您的 api 响应有关,并且可能不是组件本身的问题。
  • 我的意思是@Joao 也可能是对的,他提出了一个很好的观点,每个学生都肯定有定义的科目吗?如果他们没有,至少是一个空数组吗?

标签: javascript reactjs jsx array.prototype.map


【解决方案1】:

我找到了解决方案! 我猜这个问题不像.map 问题那么严重,而是未能完全理解我的生命周期方法。

x.subjects 是一个数组,但在首次渲染时未定义,因为前端尚未收到来自后端的响应。

为了解决这个问题,我设法做这样的事情:

<ul>
   {x.subjects === undefined ? "loading..." : x.subjects.map((y, j) => <li key={j}>{y}</li>)}
</ul>

这允许第一次渲染避免失败。

这让我产生了另一个想法,想知道这是否是加载初始状态的正确方法。现在我是:

  • 在组件的异步调用(使用 redux thunk)中调度操作
  • 这会更新 store 并将数据向下传递到 props
  • 完成后,组件会重新渲染,显示从后端接收到的数据

我想知道是否有更好的方法来做到这一点......

【讨论】:

  • 可以设置道具的状态。然后在构造函数上,您可以初始化 stateName : [] 从那里您可以看到它永远不会是 undefined ,默认情况下它将是一个空数组
【解决方案2】:

我尝试了相同的逻辑。它在下面的编译器中工作得很好。

let students = [
        {
          "name": "person",
          "photoURL": "https://via.placeholder.com/100x100",
          "subjects":[
            "physics",
            "math",
            "english"
          ],
          "nextClass": "August 29th, 2018"
        },
        {
          "name": "human",
          "photoURL": "https://via.placeholder.com/100x100",
          "subjects":[
            "chemistry",
            "math",
            "french"
          ],
          "nextClass": "August 27th, 2018"
        }]
        
const Component = (props) => {

    return(
          <div id="display-students">
            {props.students.map((x,i) =>{
              return (
                <div className="student" key={i}>
                  <h2>{x.name}</h2>
                  <img src={x.photoURL} alt="profile"/>
                  <h3>Subjects: </h3>
                  <ul>
                      {x.subjects.map((y) => <li>{y}</li>)}
                  </ul>
                </div>  
              )
            })} 
          </div>
        )
   }
   
   ReactDOM.render(<Component students={students} />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
<div id="app"/>

【讨论】:

    猜你喜欢
    • 2018-01-01
    • 1970-01-01
    • 2021-08-18
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多