简体   繁体   中英

Double for loops in React using .map

I'm trying to create a double for loop in React for some JSON content that I created:

"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"
        }]

In my JSX, I'm trying to loop through the student objects and then loop through all the subjects again to make an unordered list:

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

However, this error shows up in the browser:

在此处输入图片说明

When I try and render out

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

I see the content in the array all mashed up into one string: 在此处输入图片说明

Any pointers on why this is happening? Can we even use double for loops in JSX?

Thanks in advance!

I tried the same logic. It works perfectly fine in the below compiler.

 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"/>

I found the solution! I guess the issue wasn't as much as a .map issue as much as failing to fully understand my life-cycle methods.

x.subjects is an array, however it's undefined on first-render because the response from the back-end hasn't been received by the front-end yet.

To fix this, I managed to do something like this:

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

This allowed for the first render to avoid failing.

This spun me off on another tangent wondering if this is the right way to load initial state. Right now I'm:

  • dispatching an action in an async call (using redux thunk) in the component
  • This updates the store and passes data down into the props
  • Once it does that, the component re-renders, displaying the data it received from the back-end

I wonder if there's a better way to do this...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM