Passing Props

Props are one of the most important concepts in React because they allow components to share data with each other. In most React applications, data flows from a parent component to a child component through props.

For example, a parent component might have a user’s name, course title, price, or progress percentage. Instead of hardcoding those values inside a child component, the parent can pass them as props.

Understanding how to pass props is essential for building reusable and dynamic React components.

What Does Passing Props Mean?

Passing props means sending data from one React component to another, usually from a parent component to a child component.

Think of props as information that a parent gives to its child.

function App() {
  return <User name="Karimulla" />;
}

Here:

  • App is the parent component.
  • User is the child component.
  • name is a prop.
  • "Karimulla" is the value passed through that prop.

The child can then read the prop.

function User(props) {
  return <h2>Hello, {props.name}</h2>;
}

The browser displays:

Hello, Karimulla

The basic flow is:

Parent Component
       ↓
    Props
       ↓
Child Component
       ↓
   Render UI

Why Do We Pass Props?

Without props, reusable components would often need to contain hardcoded data.

For example:

function User() {
  return <h2>Welcome, Karimulla</h2>;
}

This component can only display one specific name.

If you want to display different users, you would need different components or additional hardcoded values.

Props solve this problem.

function User({ name }) {
  return <h2>Welcome, {name}</h2>;
}

Now the same component can be reused:

<User name="Karimulla" />
<User name="Rahul" />
<User name="John" />

The component remains the same, while the data changes.

Passing a String Prop

The simplest way to pass a prop is to provide a string value.

function App() {
  return <Welcome name="Karimulla" />;
}

The Welcome component receives the name prop.

function Welcome(props) {
  return <h2>Welcome, {props.name}</h2>;
}

Output:

Welcome, Karimulla

You can pass multiple string props as well.

function App() {
  return (
    <User
      name="Karimulla"
      city="Hyderabad"
      role="Developer"
    />
  );
}

The child can access each value:

function User(props) {
  return (
    <div>
      <h2>{props.name}</h2>
      <p>{props.city}</p>
      <p>{props.role}</p>
    </div>
  );
}

Passing Multiple Props

A component can receive as many props as its design requires.

For example:

function App() {
  return (
    <Course
      title="React"
      level="Beginner"
      duration="8 Weeks"
    />
  );
}

The Course component receives all three props.

function Course(props) {
  return (
    <div>
      <h2>{props.title}</h2>
      <p>Level: {props.level}</p>
      <p>Duration: {props.duration}</p>
    </div>
  );
}

The result could be:

React
Level: Beginner
Duration: 8 Weeks

Each prop is an independent piece of information.

Passing Numbers as Props

Numbers need curly braces when passed through JSX.

function App() {
  return <Progress percentage={75} />;
}

Here, 75 is a JavaScript number.

The child can use it like this:

function Progress(props) {
  return <p>Progress: {props.percentage}%</p>;
}

Output:

Progress: 75%

String vs Number

These two props are different:

<Progress percentage="75" />

and:

<Progress percentage={75} />

The first passes a string.

The second passes a number.

This difference becomes important when performing calculations.

function Progress({ percentage }) {
  return <p>{percentage + 5}%</p>;
}

With:

<Progress percentage={75} />

the result is:

80%

With:

<Progress percentage="75" />

JavaScript string behavior can produce:

755

So use the appropriate data type when passing props.

Passing Boolean Props

Boolean values are also passed using curly braces.

function App() {
  return <Course available={true} />;
}

The child can read the value:

function Course({ available }) {
  return <p>{available ? "Available" : "Not Available"}</p>;
}

Output:

Available

Boolean Shorthand

When you want to pass true, React allows a shorter syntax.

Instead of:

<Course available={true} />

you can write:

<Course available />

Both represent:

available={true}

To pass false, use:

<Course available={false} />

Passing Variables as Props

Props don’t have to contain hardcoded values.

You can store data in variables and pass those variables.

function App() {
  const courseName = "React";
  const courseLevel = "Beginner";

  return (
    <Course
      name={courseName}
      level={courseLevel}
    />
  );
}

The child receives the values:

function Course({ name, level }) {
  return (
    <div>
      <h2>{name}</h2>
      <p>{level}</p>
    </div>
  );
}

This approach becomes especially useful when data comes from APIs, state, databases, or user interactions.

Passing Objects as Props

You can pass an entire object to a component.

function App() {
  const user = {
    name: "Karimulla",
    role: "Frontend Developer",
    experience: 1
  };

  return <User user={user} />;
}

The child receives the object:

function User({ user }) {
  return (
    <div>
      <h2>{user.name}</h2>
      <p>{user.role}</p>
      <p>{user.experience} year experience</p>
    </div>
  );
}

Objects are useful when several related values belong to the same entity.

For example:

const course = {
  title: "React",
  level: "Intermediate",
  duration: "6 Weeks",
  students: 1200
};

You can pass the complete object:

<Course course={course} />

Passing Arrays as Props

Arrays can also be passed to components.

function App() {
  const topics = [
    "JSX",
    "Components",
    "Props",
    "State"
  ];

  return <TopicList topics={topics} />;
}

The child can use the array:

function TopicList({ topics }) {
  return (
    <ul>
      {topics.map((topic) => (
        <li key={topic}>{topic}</li>
      ))}
    </ul>
  );
}

This produces:

  • JSX
  • Components
  • Props
  • State

Passing arrays is particularly useful for lists, menus, navigation items, products, courses, and other repeated UI.

Passing Functions as Props

Functions can also be passed as props.

This is an important React pattern because it allows a child component to trigger behavior defined by its parent.

function App() {
  function handleClick() {
    alert("Button clicked");
  }

  return <Button onClick={handleClick} />;
}

The child receives the function:

function Button({ onClick }) {
  return (
    <button onClick={onClick}>
      Click Me
    </button>
  );
}

When the button is clicked, the child’s event handler calls the function provided by the parent.

The flow looks like:

Parent
  │
  │ passes function
  ↓
Child
  │
  │ calls function
  ↓
Parent's logic runs

This pattern is commonly used for child-to-parent communication.

Passing JSX as Props

Props can even contain JSX.

For example:

function App() {
  return (
    <Card
      title="React"
      icon={<span>⚛️</span>}
    />
  );
}

The child can render the JSX:

function Card({ title, icon }) {
  return (
    <div>
      {icon}
      <h2>{title}</h2>
    </div>
  );
}

This allows a component to accept UI content from its parent without hardcoding that content.

The children prop is another common and especially useful way of passing JSX content.

Passing Props to Multiple Component Instances

The same component can be rendered multiple times with different props.

function App() {
  return (
    <Course
      title="React"
      level="Beginner"
    />
  );
}

You can render it again:

function App() {
  return (
    <>
      <Course title="React" level="Beginner" />
      <Course title="JavaScript" level="Intermediate" />
      <Course title="Python" level="Advanced" />
    </>
  );
}

The component is reused three times.

Each instance receives its own prop values.

This is one of the main reasons props are so important for reusable components.

Passing Props Through Component Levels

Sometimes data needs to travel through more than one component.

For example:

App
 ↓
Dashboard
 ↓
CourseCard

The App component can pass data to Dashboard:

<Dashboard course={course} />

Then Dashboard can pass it to CourseCard:

<CourseCard course={course} />

Finally, CourseCard can use it:

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

This is called prop drilling when props are passed through components that don’t themselves need the data, simply to reach a deeper component.

Prop drilling is not automatically bad. For a small component tree, it can be perfectly reasonable.

For larger applications, React Context or state-management solutions can sometimes reduce unnecessary prop passing.

Passing Props with Destructuring

You can access props using the props object:

function Course(props) {
  return <h2>{props.title}</h2>;
}

Or destructure them directly:

function Course({ title }) {
  return <h2>{title}</h2>;
}

With multiple props:

function Course({ title, level, duration }) {
  return (
    <div>
      <h2>{title}</h2>
      <p>{level}</p>
      <p>{duration}</p>
    </div>
  );
}

Both approaches work.

Destructuring is often preferred when the component uses several props because it makes the component’s expected data easier to see.

Passing Props to Control Styling

Props can also control how a component looks.

For example:

function App() {
  return (
    <Button variant="primary">
      Start Learning
    </Button>
  );
}

The component can use the prop:

function Button({ variant, children }) {
  return (
    <button className={`button ${variant}`}>
      {children}
    </button>
  );
}

Now the same component could support:

<Button variant="primary">Start Learning</Button>

<Button variant="secondary">View Course</Button>

<Button variant="danger">Delete</Button>

Instead of creating separate components such as:

PrimaryButton
SecondaryButton
DangerButton

you can create one reusable Button component with a controlled API.

Passing Props to Control Content

Props can determine what a component displays.

function CourseCard({ title, description }) {
  return (
    <article>
      <h2>{title}</h2>
      <p>{description}</p>
    </article>
  );
}

Different data produces different content:

<CourseCard
  title="Learn React"
  description="Build modern user interfaces."
/>

<CourseCard
  title="Learn JavaScript"
  description="Understand the language behind modern web development."
/>

The component structure stays the same.

Only the data changes.

Practical Example: Course Cards

Imagine Web4Learners has a course page.

Instead of creating separate components for every course, create one reusable component:

function CourseCard({ title, level, lessons, progress }) {
  return (
    <article className="course-card">
      <h2>{title}</h2>
      <p>Level: {level}</p>
      <p>Lessons: {lessons}</p>
      <p>Progress: {progress}%</p>
    </article>
  );
}

The parent can provide different information:

function App() {
  return (
    <main>
      <CourseCard
        title="React"
        level="Beginner"
        lessons={40}
        progress={75}
      />

      <CourseCard
        title="JavaScript"
        level="Intermediate"
        lessons={60}
        progress={50}
      />

      <CourseCard
        title="CSS"
        level="Beginner"
        lessons={35}
        progress={90}
      />
    </main>
  );
}

The result is three different cards created from the same component.

This demonstrates the central idea of props:

The component defines how the UI works, while props provide the data that makes each instance different.

Props Flow From Parent to Child

React generally follows a one-way data flow.

Parent
   │
   ├── name
   ├── level
   └── progress
        ↓
      Child

For example:

<CourseCard
  name="React"
  level="Beginner"
  progress={75}
/>

The child receives those values.

function CourseCard({ name, level, progress }) {
  // use props here
}

The child should not directly modify its props.

If the value needs to change, the parent generally changes the value it passes, often by updating its own state.

Props Are Read-Only

A component should treat its props as read-only.

For example, avoid doing this:

function User(props) {
  props.name = "John";

  return <h2>{props.name}</h2>;
}

Instead, if the data needs to change, the appropriate owner of that data should update it and pass the new value down.

For example:

function App() {
  const [name, setName] = useState("Karimulla");

  return <User name={name} />;
}

When the parent changes name, React can render the child with the new prop value.

The important distinction is:

A child cannot mutate the prop directly, but a prop value can change when the parent renders the child with a different value.

Common Mistakes When Passing Props

Forgetting Curly Braces for JavaScript Values

Incorrect:

<Course progress="75" />

if you intended a number.

Correct:

<Course progress={75} />

Calling a Function Instead of Passing It

Suppose you have:

function handleClick() {
  console.log("Clicked");
}

Usually, pass the function:

<Button onClick={handleClick} />

rather than:

<Button onClick={handleClick()} />

The second version calls the function immediately during rendering instead of passing the function for the event to invoke later.

Using the Wrong Prop Name

If the parent passes:

<Course courseTitle="React" />

but the child expects:

function Course({ title }) {
  return <h2>{title}</h2>;
}

title will be undefined.

The prop names must match:

function Course({ courseTitle }) {
  return <h2>{courseTitle}</h2>;
}

Mutating Props

Avoid changing props directly.

props.progress = 100;

Props should be treated as read-only.

Passing Too Much Unrelated Data

Don’t pass every piece of parent data into every child.

Instead of:

<User
  name={name}
  age={age}
  city={city}
  theme={theme}
  courses={courses}
  settings={settings}
/>

when the component only needs name and city, pass what it actually needs:

<User
  name={name}
  city={city}
/>

A focused prop API makes components easier to understand and reuse.

Best Practices for Passing Props

  • Use descriptive prop names.
  • Pass only the data a component actually needs.
  • Use the correct JavaScript data type.
  • Use curly braces for JavaScript expressions.
  • Treat props as read-only.
  • Use functions as props for event communication.
  • Use objects when several values belong together.
  • Use arrays for collections of related data.
  • Use destructuring when it improves readability.
  • Keep reusable components focused.
  • Avoid unnecessarily passing props through many component levels.
  • Choose component boundaries based on responsibility rather than simply splitting every element.

A Simple Mental Model

When you see:

<Course
  title="React"
  level="Beginner"
  progress={75}
/>

read it as:

Create a Course component
and give it:

title → "React"
level → "Beginner"
progress → 75

Inside the component:

function Course({ title, level, progress }) {
  // use the received values
}

Think of props as inputs to a component.

          Props
            ↓
     ┌──────────────┐
     │   Component  │
     │              │
     │   UI Logic   │
     └──────────────┘
            ↓
       Rendered UI

Passing Props Cheat Sheet

RequirementExample
Stringname="Karimulla"
Numberprogress={75}
Booleanavailable={true}
Boolean shorthandavailable
Variablename={userName}
Objectuser={user}
Arraytopics={topics}
FunctiononClick={handleClick}
JSXicon={<Icon />}
Multiple props<Course title="React" level="Beginner" />
Read propprops.title
Destructurefunction Course({ title })

Practice Exercise

Create a reusable ProfileCard component.

The parent should pass:

  • name
  • role
  • location
  • experience
  • isAvailable

Start with:

function App() {
  return (
    <ProfileCard
      name="Karimulla"
      role="Frontend Developer"
      location="Hyderabad"
      experience={1}
      isAvailable={true}
    />
  );
}

Then create the ProfileCard component and display all five values.

After that, try creating two more profile cards using different prop values.

Image Placement

Place an image immediately after the section explaining “What Does Passing Props Mean?”

The image should visually show a parent React component passing several values into a child component. Use a modern 16:9 developer-style infographic with a clean React aesthetic. Show App on the left, arrows labeled props in the middle, and Course on the right with examples such as title, level, and progress. Keep the text minimal and make the data flow visually obvious.

Caption: Passing data from a parent component to a child component using props.

Alt text: React parent component passing props to a child component.

Key Takeaways

  • Props allow components to receive data from other components.
  • Props are most commonly passed from a parent to a child.
  • Props make components reusable and dynamic.
  • Props can contain strings, numbers, booleans, objects, arrays, functions, and JSX.
  • JavaScript values such as numbers and variables are passed using curly braces.
  • Functions can be passed as props to allow child components to trigger parent logic.
  • The receiving component should treat props as read-only.
  • The same component can be reused with different prop values.
  • Good prop design makes components easier to understand and maintain.
  • Props are one of the foundations of React’s one-way data flow.

Leave a Comment