all topics

Lists

Rendering a list with .map()

Turn an array of data into an array of elements, one component per item.

jsx
const movies = [
    { id: 1, title: "Dune", genre: "Sci-Fi", rating: 5 },
    { id: 2, title: "Her", genre: "Drama", rating: 4 },
    { id: 3, title: "Parasite", genre: "Thriller", rating: 5 }
]
 
{movies.map(movie => (
    <MovieCard
        key={movie.id}
        title={movie.title}
        genre={movie.genre}
        rating={movie.rating}
    />
))}
  • .map() runs once per array item and returns a new array, here an array of <MovieCard /> elements, and JSX is happy to render an array directly inside {}.
  • Each call passes that item's own fields down as props, same as writing them out by hand, just generated instead of typed.

Why every mapped item needs a key

Two separate channels of information whenever you render a list this way.

  • key={movie.id} isn't a prop. It's metadata React reads for itself, to answer "who is this?" when the list changes later.
  • movie={movie} (or the individual fields) is the actual prop data, what the component needs to render, answering "what does this item need to show?"
jsx
props = {
    movie: { id: 1, title: "Dune", genre: "Sci-Fi" }
}
// never props.key

What React actually uses key for

Say the list changes:

  • Before: 1 Dune, 2 Her, 3 Parasite.
  • After: 1 Dune, 3 Parasite.

With stable keys, React can tell 1 and 3 are the same items as before, only 2 was removed. Without a stable identity, React has no reliable way to match old items to new ones, and can end up re-rendering or reordering more than it needs to.

key isn't a prop, on purpose

It never reaches the component. props.key is always undefined, not a bug, just how it's designed: key is attached to the element for React's own bookkeeping, not handed down as data.

jsx
function MovieCard(props) {
    console.log(props.key) // undefined, always
}

Need that same id for the component's own logic, not just for React's benefit? Pass it again as an actual prop, under a different name.

jsx
<MovieCard key={movie.id} movie={movie} id={movie.id} />
 
function MovieCard({ movie, id }) {
    // id is available here, key never was
}

The one-line memory hook

key tells React which item this is. Props tell the component what data this item has.