Rendering a List of Components

Using map like this is super common in React. You need to know how this code works and how to use it.

jokes.map(joke => (
<Joke key={joke.id} joke={joke.joke} rating={joke.rating} />
))
jokes.map(joke => (
<Joke key={joke.id} joke={joke.joke} rating={joke.rating} />
))
jokes.map(joke => (
<Joke key={joke.id} joke={joke.joke} rating={joke.rating} />
))
jokes.map(joke => (
<Joke key={joke.id} joke={joke.joke} rating={joke.rating} />
))

Arrays of Components

A JSX component is a normal JavaScript value, so we can store them in an array just like any other value.

const jokesComponents = [
<Joke joke={"Torn jeans? Rip off"} rating={2} />,
<Joke joke={"A Broken pencil is Pointless"} rating={3} />
]
const jokesComponents = [
<Joke joke={"Torn jeans? Rip off"} rating={2} />,
<Joke joke={"A Broken pencil is Pointless"} rating={3} />
]
const jokesComponents = [
<Joke joke={"Torn jeans? Rip off"} rating={2} />,
<Joke joke={"A Broken pencil is Pointless"} rating={3} />
]
const jokesComponents = [
<Joke joke={"Torn jeans? Rip off"} rating={2} />,
<Joke joke={"A Broken pencil is Pointless"} rating={3} />
]

We can render a JavaScript value inside of JSX using {}. An array of components is just a JS value.

page.tsx
const jokesComponents = [
<Joke joke={"Torn jeans? Rip off"} rating={2} />,
<Joke joke={"A Broken pencil is Pointless"} rating={3} />
]
export default function Page() {
return (
<div>
{jokesComponents}
</div>
)
}
page.tsx
const jokesComponents = [
<Joke joke={"Torn jeans? Rip off"} rating={2} />,
<Joke joke={"A Broken pencil is Pointless"} rating={3} />
]
export default function Page() {
return (
<div>
{jokesComponents}
</div>
)
}
page.tsx
const jokesComponents = [
<Joke joke={"Torn jeans? Rip off"} rating={2} />,
<Joke joke={"A Broken pencil is Pointless"} rating={3} />
]
export default function Page() {
return (
<div>
{jokesComponents}
</div>
)
}
page.tsx
const jokesComponents = [
<Joke joke={"Torn jeans? Rip off"} rating={2} />,
<Joke joke={"A Broken pencil is Pointless"} rating={3} />
]
export default function Page() {
return (
<div>
{jokesComponents}
</div>
)
}

This is a really nice feature of JSX, but seems kind of pointless right now since we could have just written the Joke components directly in the JSX. But in a real application, this data is going to be coming from some other data source like a database.

No matter where the data is coming from, it's very likely (almost guaranteed) that we'll end up with an array of objects that we need to render as components.

Something like this:

const jokes = [
{
id: 1,
joke: "Torn jeans? Rip off",
rating: 2,
},
{
id: 2,
joke: "A Broken pencil is Pointless",
rating: 3,
}
]
const jokes = [
{
id: 1,
joke: "Torn jeans? Rip off",
rating: 2,
},
{
id: 2,
joke: "A Broken pencil is Pointless",
rating: 3,
}
]
const jokes = [
{
id: 1,
joke: "Torn jeans? Rip off",
rating: 2,
},
{
id: 2,
joke: "A Broken pencil is Pointless",
rating: 3,
}
]
const jokes = [
{
id: 1,
joke: "Torn jeans? Rip off",
rating: 2,
},
{
id: 2,
joke: "A Broken pencil is Pointless",
rating: 3,
}
]

All we need to do is take the array of objects and turn it into an array of components. Then we can render the components in JSX just as we did before.

For Loop

This can of course be done with a for loop:

page.tsx
const jokesComponents = []
for (let i = 0; i < jokes.length; i++) {
const joke = jokes[i]
jokesComponents.push(
<Joke joke={joke.joke} rating={joke.rating} />
)
}

return (
<div>
{jokesComponents}
</div>
)
page.tsx
const jokesComponents = []
for (let i = 0; i < jokes.length; i++) {
const joke = jokes[i]
jokesComponents.push(
<Joke joke={joke.joke} rating={joke.rating} />
)
}

return (
<div>
{jokesComponents}
</div>
)
page.tsx
const jokesComponents = []
for (let i = 0; i < jokes.length; i++) {
const joke = jokes[i]
jokesComponents.push(
<Joke joke={joke.joke} rating={joke.rating} />
)
}

return (
<div>
{jokesComponents}
</div>
)
page.tsx
const jokesComponents = []
for (let i = 0; i < jokes.length; i++) {
const joke = jokes[i]
jokesComponents.push(
<Joke joke={joke.joke} rating={joke.rating} />
)
}

return (
<div>
{jokesComponents}
</div>
)

Map

A much better, and much more common way of doing this is with the map function:

page.tsx
const jokesComponents = jokes.map(joke => (
<Joke joke={joke.joke} rating={joke.rating} />
))

return (
<div>
{jokesComponents}
</div>
)
page.tsx
const jokesComponents = jokes.map(joke => (
<Joke joke={joke.joke} rating={joke.rating} />
))

return (
<div>
{jokesComponents}
</div>
)
page.tsx
const jokesComponents = jokes.map(joke => (
<Joke joke={joke.joke} rating={joke.rating} />
))

return (
<div>
{jokesComponents}
</div>
)
page.tsx
const jokesComponents = jokes.map(joke => (
<Joke joke={joke.joke} rating={joke.rating} />
))

return (
<div>
{jokesComponents}
</div>
)

Keys

Make sure you always include a key for each component in the array. This must be unique for each component in that array, so an id is a good choice.

const jokesComponents = jokes.map(joke => (
<Joke
key={joke.id}
joke={joke.joke}
rating={joke.rating}
/>
))
const jokesComponents = jokes.map(joke => (
<Joke
key={joke.id}
joke={joke.joke}
rating={joke.rating}
/>
))
const jokesComponents = jokes.map(joke => (
<Joke
key={joke.id}
joke={joke.joke}
rating={joke.rating}
/>
))
const jokesComponents = jokes.map(joke => (
<Joke
key={joke.id}
joke={joke.joke}
rating={joke.rating}
/>
))

Read more about Why does React need keys?: https://beta.reactjs.org/learn/rendering-lists#why-does-react-need-keys