React Props with Arrays

Arrays are one of the most common data types you will pass to React components through props.

When a component needs to display multiple items, such as a list of products, users, courses, menu items, or social media posts, an array is often the natural way to represent that data.

For example, instead of passing one course to a component at a time, you can pass an entire array of courses:

const courses = ["React", "JavaScript", "Python"];

<CourseList courses={courses} />

The CourseList component can then receive the array and use JavaScript methods such as map() to display each item.

Understanding arrays as props is important because many real React applications work with collections of data received from APIs, databases, or application state.

What Are Array Props?

An array prop is simply an array passed from a parent component to a child component.

Here is a basic example:

function App() {
  const skills = ["HTML", "CSS", "JavaScript"];

  return <Skills skills={skills} />;
}

function Skills(props) {
  return (
    <div>
      <p>{props.skills[0]}</p>
      <p>{props.skills[1]}</p>
      <p>{props.skills[2]}</p>
    </div>
  );
}

export default App;

The parent component creates the skills array and passes it to the Skills component.

The child receives that array through the skills prop.

The data flow looks like this:

Parent → Array Prop → Child

Passing an Array as a Prop

You can pass an array using curly braces in JSX.

function App() {
  const languages = ["JavaScript", "Java", "Python"];

  return <LanguageList languages={languages} />;
}

The curly braces are required because languages is a JavaScript variable.

You can also pass an array directly:

function App() {
  return (
    <LanguageList
      languages={["JavaScript", "Java", "Python"]}
    />
  );
}

Both approaches work.

However, storing the array in a variable is often easier to read, especially when the array contains many items.

Reading an Array Prop

The child component receives the array through the props object.

function Skills(props) {
  return (
    <div>
      <p>{props.skills[0]}</p>
      <p>{props.skills[1]}</p>
      <p>{props.skills[2]}</p>
    </div>
  );
}

Here:

  • props is the props object.
  • skills is the prop name.
  • props.skills is the array.
  • [0], [1], and [2] access individual array elements.

Remember that JavaScript arrays use zero-based indexing.

Index:    0          1           2
Value:  React    JavaScript    Python

Therefore:

props.skills[0]

returns "React".

Using Props Destructuring

Instead of repeatedly writing props.skills, you can destructure the prop.

function Skills({ skills }) {
  return (
    <div>
      <p>{skills[0]}</p>
      <p>{skills[1]}</p>
      <p>{skills[2]}</p>
    </div>
  );
}

This is usually cleaner when the component uses the array several times.

Rendering an Array with map()

In real applications, you usually don’t know exactly how many items an array will contain.

Instead of manually accessing every index, use JavaScript’s map() method.

function Skills({ skills }) {
  return (
    <ul>
      {skills.map((skill) => (
        <li key={skill}>{skill}</li>
      ))}
    </ul>
  );
}

Now the component can render any number of skills.

If the parent provides:

const skills = ["HTML", "CSS", "JavaScript", "React"];

The component generates a list containing all four skills.

This pattern is extremely common in React.

Why map() Is Useful

Consider an array containing 100 products.

You would not want to write:

<p>{products[0]}</p>
<p>{products[1]}</p>
<p>{products[2]}</p>

Instead, map() allows React to generate the UI based on the data.

{products.map((product) => (
  <p key={product}>{product}</p>
))}

The number of rendered elements automatically follows the number of items in the array.

Arrays of Objects as Props

In practical React applications, arrays often contain objects instead of simple strings.

For example:

const courses = [
  {
    id: 1,
    title: "React",
    level: "Beginner"
  },
  {
    id: 2,
    title: "JavaScript",
    level: "Intermediate"
  },
  {
    id: 3,
    title: "Node.js",
    level: "Advanced"
  }
];

You can pass the entire array to a component.

function App() {
  const courses = [
    {
      id: 1,
      title: "React",
      level: "Beginner"
    },
    {
      id: 2,
      title: "JavaScript",
      level: "Intermediate"
    },
    {
      id: 3,
      title: "Node.js",
      level: "Advanced"
    }
  ];

  return <CourseList courses={courses} />;
}

The child can then render each object.

function CourseList({ courses }) {
  return (
    <div>
      {courses.map((course) => (
        <article key={course.id}>
          <h2>{course.title}</h2>
          <p>{course.level}</p>
        </article>
      ))}
    </div>
  );
}

This pattern is widely used for:

  • Product lists
  • Course catalogs
  • User lists
  • Blog posts
  • Search results
  • Navigation menus
  • Notifications
  • Dashboard data
  • API responses

Passing Arrays to Reusable Components

Arrays make components highly reusable.

For example, you can create one CourseList component and provide different course arrays.

function App() {
  const frontendCourses = [
    "HTML",
    "CSS",
    "JavaScript",
    "React"
  ];

  const backendCourses = [
    "Java",
    "Spring Boot",
    "Node.js",
    "Django"
  ];

  return (
    <>
      <CourseList courses={frontendCourses} />
      <CourseList courses={backendCourses} />
    </>
  );
}

The same component handles both arrays.

This is one of the main benefits of passing data through props.

Passing Multiple Array Props

A component can receive more than one array.

function App() {
  const frontend = ["HTML", "CSS", "React"];
  const backend = ["Java", "Spring Boot", "SQL"];

  return (
    <SkillSection
      frontend={frontend}
      backend={backend}
    />
  );
}

function SkillSection({ frontend, backend }) {
  return (
    <div>
      <h2>Frontend</h2>

      {frontend.map((skill) => (
        <p key={skill}>{skill}</p>
      ))}

      <h2>Backend</h2>

      {backend.map((skill) => (
        <p key={skill}>{skill}</p>
      ))}
    </div>
  );
}

There is no limit to the number of props a component can receive, but components should still have a clear and understandable API.

Arrays and the key Prop

When rendering an array with map(), React expects each sibling element to have a unique key.

For example:

function Users({ users }) {
  return (
    <div>
      {users.map((user) => (
        <p key={user.id}>{user.name}</p>
      ))}
    </div>
  );
}

The key helps React identify which items have changed, been added, or been removed.

A stable unique ID is generally the best choice.

Prefer Stable IDs

If your objects contain IDs, use them.

{users.map((user) => (
  <div key={user.id}>
    {user.name}
  </div>
))}

Avoid using array indexes as keys when the list can be reordered, inserted into, or deleted from.

For example:

{users.map((user, index) => (
  <div key={index}>
    {user.name}
  </div>
))}

Using the index is not automatically wrong, but it can cause incorrect component identity when the order of items changes.

Arrays from State

Array props are frequently connected to state.

The parent component may store an array in state and pass it to a child.

import { useState } from "react";

function App() {
  const [skills, setSkills] = useState([
    "HTML",
    "CSS"
  ]);

  return <Skills skills={skills} />;
}

function Skills({ skills }) {
  return (
    <ul>
      {skills.map((skill) => (
        <li key={skill}>{skill}</li>
      ))}
    </ul>
  );
}

export default App;

Whenever the parent updates the skills state, the child receives the updated array on the next render.

This creates a common React pattern:

State in Parent → Props → Child UI

Updating an Array in the Parent

A child should not directly modify an array prop.

Instead, the parent that owns the state should update the array.

For example:

import { useState } from "react";

function App() {
  const [skills, setSkills] = useState([
    "HTML",
    "CSS"
  ]);

  function addSkill() {
    setSkills((currentSkills) => [
      ...currentSkills,
      "React"
    ]);
  }

  return (
    <>
      <button onClick={addSkill}>
        Add Skill
      </button>

      <Skills skills={skills} />
    </>
  );
}

function Skills({ skills }) {
  return (
    <ul>
      {skills.map((skill) => (
        <li key={skill}>{skill}</li>
      ))}
    </ul>
  );
}

export default App;

The spread syntax creates a new array containing the existing items plus the new item.

This is the preferred approach for updating arrays in React state.

Filtering an Array Prop

You can also use JavaScript array methods to filter data before rendering it.

function Products({ products }) {
  const availableProducts = products.filter(
    (product) => product.available
  );

  return (
    <div>
      {availableProducts.map((product) => (
        <p key={product.id}>
          {product.name}
        </p>
      ))}
    </div>
  );
}

Here, only products whose available property is true are displayed.

You can use methods such as:

MethodCommon purpose
map()Transform or render every item
filter()Select specific items
find()Find one matching item
some()Check whether at least one item matches
every()Check whether all items match
slice()Create a portion of an array

These are JavaScript features, but they are used constantly when working with React data.

Passing an Array to a Child Component

A common application structure might look like this:

App
│
├── CourseList
│   ├── CourseCard
│   ├── CourseCard
│   └── CourseCard
│
└── Footer

The parent can pass an array to CourseList.

CourseList can then pass individual objects to CourseCard.

function App() {
  const courses = [
    {
      id: 1,
      title: "React",
      level: "Beginner"
    },
    {
      id: 2,
      title: "JavaScript",
      level: "Intermediate"
    }
  ];

  return <CourseList courses={courses} />;
}

function CourseList({ courses }) {
  return (
    <div>
      {courses.map((course) => (
        <CourseCard
          key={course.id}
          course={course}
        />
      ))}
    </div>
  );
}

function CourseCard({ course }) {
  return (
    <article>
      <h2>{course.title}</h2>
      <p>{course.level}</p>
    </article>
  );
}

export default App;

This separates responsibilities:

  • App owns the data.
  • CourseList handles the collection.
  • CourseCard handles one course.

This approach becomes especially useful as applications grow.

Arrays Received from APIs

Many real applications receive arrays from APIs.

An API might return data such as:

[
  {
    id: 101,
    name: "Alice"
  },
  {
    id: 102,
    name: "John"
  },
  {
    id: 103,
    name: "Sara"
  }
]

After retrieving the data, a component can receive it as a prop:

function UserList({ users }) {
  return (
    <ul>
      {users.map((user) => (
        <li key={user.id}>
          {user.name}
        </li>
      ))}
    </ul>
  );
}

This is why understanding array props is an important step toward working with real-world React applications.

Avoid Mutating Array Props

Props should be treated as read-only.

Do not directly modify an array received through props.

Avoid code like:

function Skills({ skills }) {
  skills.push("React");

  return <p>{skills.join(", ")}</p>;
}

The child is mutating data owned by another component.

Instead, if the child needs to request a change, the parent can provide a callback function.

function App() {
  const [skills, setSkills] = useState([
    "HTML",
    "CSS"
  ]);

  function addSkill(skill) {
    setSkills((currentSkills) => [
      ...currentSkills,
      skill
    ]);
  }

  return (
    <Skills
      skills={skills}
      onAddSkill={addSkill}
    />
  );
}

This keeps ownership of the data with the parent.

Array Props vs Multiple Individual Props

Suppose you have three courses.

You could pass them individually:

<Course
  first="React"
  second="JavaScript"
  third="Python"
/>

Or you could pass them as an array:

<CourseList
  courses={["React", "JavaScript", "Python"]}
/>

The array approach is usually more suitable when the data represents a collection.

It also makes the component easier to reuse when the number of items changes.

Arrays of Objects vs Arrays of Strings

Both are useful.

Array of Strings

Use a simple array when each item only needs one value.

const technologies = [
  "React",
  "Vue",
  "Angular"
];

Array of Objects

Use objects when each item needs multiple properties.

const technologies = [
  {
    id: 1,
    name: "React",
    type: "Library"
  },
  {
    id: 2,
    name: "Angular",
    type: "Framework"
  }
];

The second approach provides more information for the UI.

Common Mistakes with Array Props

Forgetting Curly Braces

Incorrect:

<CourseList courses="courses" />

This passes the literal string "courses".

Correct:

<CourseList courses={courses} />

Forgetting map()

If you want to display every item, manually accessing indexes is usually unnecessary.

Prefer:

{courses.map((course) => (
  <p key={course.id}>{course.title}</p>
))}

Missing Keys

Incorrect:

{courses.map((course) => (
  <p>{course.title}</p>
))}

Correct:

{courses.map((course) => (
  <p key={course.id}>{course.title}</p>
))}

Mutating the Prop

Avoid modifying the array directly inside the child component.

Treat props as read-only.

Assuming the Array Always Has Data

A component may receive an empty array.

For example:

function CourseList({ courses }) {
  if (courses.length === 0) {
    return <p>No courses available.</p>;
  }

  return (
    <ul>
      {courses.map((course) => (
        <li key={course.id}>{course.title}</li>
      ))}
    </ul>
  );
}

Handling empty states makes components more robust.

Best Practices for Array Props

Keep these practices in mind:

  • Use meaningful prop names such as courses, users, or products.
  • Use map() to render collections.
  • Provide stable keys for list items.
  • Prefer unique IDs as keys when available.
  • Treat props as read-only.
  • Keep array ownership clear.
  • Update arrays through the component that owns the state.
  • Use arrays of objects when items need multiple properties.
  • Handle empty arrays when appropriate.
  • Keep list-rendering components focused on their responsibility.
  • Avoid passing unnecessary data.
  • Use destructuring when it improves readability.

Practical Example: Web4Learners Course List

Let’s create a small course-list example similar to something you might use on a tutorial website.

function App() {
  const courses = [
    {
      id: 1,
      title: "React Tutorial",
      level: "Beginner",
      duration: "6 hours"
    },
    {
      id: 2,
      title: "JavaScript Tutorial",
      level: "Intermediate",
      duration: "8 hours"
    },
    {
      id: 3,
      title: "CSS Tutorial",
      level: "Beginner",
      duration: "4 hours"
    }
  ];

  return <CourseList courses={courses} />;
}

function CourseList({ courses }) {
  return (
    <section>
      <h1>Web4Learners Courses</h1>

      {courses.map((course) => (
        <CourseCard
          key={course.id}
          course={course}
        />
      ))}
    </section>
  );
}

function CourseCard({ course }) {
  return (
    <article>
      <h2>{course.title}</h2>
      <p>Level: {course.level}</p>
      <p>Duration: {course.duration}</p>
    </article>
  );
}

export default App;

This example demonstrates several React concepts together:

  • Arrays
  • Objects
  • Props
  • Destructuring
  • map()
  • Keys
  • Component composition
  • Reusable components

The important idea is that the parent owns the collection while child components receive the data they need through props.

Image Placement

Place image immediately after the “Arrays of Objects as Props” section.

Image description: A modern React data-flow infographic showing an array of course objects moving from a parent App component through a courses prop into a CourseList component, where map() creates multiple CourseCard components. Use a clean developer-focused visual style with React-inspired elements, subtle gradients, code snippets, and clear arrows. Keep text minimal and make the component hierarchy visually obvious.

Caption: Passing an array of objects from a parent component to reusable React child components.

Alt text: React array props flowing from a parent component to a list of reusable child components.

Practice Exercise

Create a React application that displays a list of technologies.

Start with this array:

const technologies = [
  {
    id: 1,
    name: "React",
    category: "Frontend"
  },
  {
    id: 2,
    name: "Spring Boot",
    category: "Backend"
  },
  {
    id: 3,
    name: "PostgreSQL",
    category: "Database"
  }
];

Then:

  • Pass the array to a TechnologyList component.
  • Use destructuring to read the prop.
  • Use map() to render each technology.
  • Use id as the key.
  • Display the technology name.
  • Display its category.
  • Create a separate TechnologyCard component.
  • Pass each technology object to TechnologyCard.

As an additional challenge, add a fourth technology without changing the TechnologyList component.

Array Props Cheat Sheet

TaskExample
Create an arrayconst items = ["A", "B"];
Pass an array<List items={items} />
Read an arrayprops.items
Destructurefunction List({ items })
Access an itemitems[0]
Render itemsitems.map(...)
Filter itemsitems.filter(...)
Find an itemitems.find(...)
Use object propertyitem.name
Provide a keykey={item.id}
Add state item[...items, newItem]

Key Takeaways

  • Arrays can be passed to React components through props.
  • Use curly braces when passing a JavaScript array variable in JSX.
  • The child component can access the array through props or destructuring.
  • map() is commonly used to render array items.
  • Arrays of objects are especially useful for real application data.
  • List elements should generally have stable, unique keys.
  • Props should be treated as read-only.
  • The component that owns array state should be responsible for updating it.
  • Array props are commonly used with API data, lists, cards, menus, products, and courses.
  • Passing collections through props makes components reusable and data-driven.

The main pattern to remember is:

function App() {
  const items = [
    { id: 1, name: "React" },
    { id: 2, name: "JavaScript" }
  ];

  return <ItemList items={items} />;
}

function ItemList({ items }) {
  return (
    <div>
      {items.map((item) => (
        <p key={item.id}>{item.name}</p>
      ))}
    </div>
  );
}

This simple pattern is the foundation for rendering dynamic collections throughout React applications.

Leave a Comment