skip to Main Content

I have the following code from my React component:

        <div className="mainApp">
            <div className="pkgsList">
                {pkgData.map((p) => 
                    <h3 key={p.name}>{p.name}</h3>                    
                )}
                    
            </div>
        </div>
    )

In this case, pkgData is an array of objects which try to describe a package in this scenario. Each object contains a string propery name and an array property sources for which every item is also an object. I’d like to print the items inside sources (a couple properties for each item) underneath my h3 element as above, but I can’t seem to figure out how to add more HTML / JSX on what I have above – any help would be appreciated.

I keep trying to call map for each p but keep running into an error whether I wrap it on () or just {} e.g.

{p.map((s) => {
                       
})

So the resulting div code would be:

            <div className="pkgList">
                {pkgData.map((p) => 
                    <h3 key={p.name}>{p.name}</h3>
                    {p.map((c) => {
                        
                    })
                )}
            </div>

does not let my react app compile successfully.

3

Answers


  1. i think that react only want to render an element inside of map like this:

    <div className="pkgList">
                    {pkgData.map((p) => 
                        <>
                        <h3 key={p.name}>{p.name}</h3>
                        {p.map((c) => {                       })}
                        </>
                    )}
                </div>
    
    Login or Signup to reply.
  2. You can only return 1 jsx element in map like in a normal component. If you want to render multiple elements in the map function you can wrap the the code in a react fragment like so:

    <div className="mainApp">
        <div className="pkgsList">
            {pkgData.map((p) => (
                <> {/* <- this is a fragment */}
                    <h3 key={p.name}>{p.name}</h3>
                    {p.sources.map((s) => (
                        <>{/* render source here */}</>
                    ))}
                </>
            ))}
        </div>
    </div>
    
    Login or Signup to reply.
  3. Wrong map

    First, your nested map inside of pkgData.map is wrong.
    Because p itself isn’t array.
    The map should be like this,

    {p.sources.map((c) => {
        ...
        }
      )}
    

    Wrong JSX

    Second, like @David said in the comment, you can’t have more than one top-level elements because of the way JSX works under the hood.
    For example, the code

    <div className="mainApp">
      <div className="pkgsList">
        {pkgData.map((p) => 
          <h3 key={p.name}>{p.name}</h3>                    
        )}
      </div>
    </div>
    

    is equivalent to this

    <div className="mainApp">
      <div className="pkgsList">
        {pkgData.map((p) => {
          return React.createElement("h3", {key: p.name}, p.name)
          }                    
        )}
      </div>
    </div>
    

    So if you return more than one JSX elements at the top level, React.createElement cannot work.
    Therefore you should wrap the things up on the top level with some tags like fragments(<>), div, etc.

    For example,

    <div className="mainApp">
      <div className="pkgsList">
        {pkgData.map((p) =>
          <>
            <h3 key={p.name}>{p.name}</h3>
            {p.sources.map((c) => 
              <p>{c.something}</p>
            )} 
          </>
        )}
      </div>
    </div>
    

    FYI: https://react.dev/reference/react/createElement#creating-an-element-without-jsx

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search