React BasicsBeginner8 min03 / 9

Components & Props

Learn how to pass data into your components using props, make them reusable, and compose small pieces into bigger UIs.

You already know that a React component is a function that returns JSX. But right now every component you write is like a rubber stamp — it always produces the exact same output. What if you want a Button that can say "Save", "Delete", or "Submit"? What if you want a UserCard for any user, not just Jane Doe?

This is where props come in. Props (short for properties) are the mechanism React uses to pass data from a parent component down into a child component. They are the inputs that make your components flexible and reusable — the difference between a rubber stamp and a printing press.

#Your First Prop

When you write a component as a JSX tag, you can add attributes to it — just like HTML attributes on a <button> or <input>. Those attributes become the component's props.

The same Greeting component renders different output depending on the name prop it receives.
// Child component: receives props as its first argument
function Greeting(props) {
  return <h1>Hello, {props.name}!</h1>;
}

// Parent component: passes data via attributes
function App() {
  return (
    <div>
      <Greeting name="Alice" />
      <Greeting name="Bob" />
    </div>
  );
}
Think of it like

Props are like arguments to a function

Think of a component as a function you call, and props as the arguments you pass in.

``js // A regular function function greet(name) { return 'Hello, ' + name; } greet('Alice'); // => 'Hello, Alice' greet('Bob'); // => 'Hello, Bob' ``

Props work exactly the same way — they let you call the same component with different inputs and get different output every time.

#Destructuring Props (The Clean Way)

Writing props.name, props.age, props.email over and over gets noisy. Most React code uses destructuring directly in the function signature to pull out the values you need. The component works identically — it is just easier to read.

Destructuring in the parameter list is the idiomatic React style.
// Without destructuring
function UserCard(props) {
  return (
    <div>
      <h2>{props.name}</h2>
      <p>{props.role}</p>
    </div>
  );
}

// With destructuring — same result, cleaner code
function UserCard({ name, role }) {
  return (
    <div>
      <h2>{name}</h2>
      <p>{role}</p>
    </div>
  );
}

#Passing Different Types of Props

Props are not limited to strings. You can pass numbers, booleans, arrays, objects, functions — any JavaScript value. The rule is: strings go in quotes, everything else goes in curly braces {}.

Strings use quotes; numbers, booleans, and arrays use curly braces.
function ProductCard({ name, price, inStock, tags }) {
  return (
    <div>
      <h3>{name}</h3>
      <p>${price.toFixed(2)}</p>
      <p>{inStock ? 'In stock' : 'Sold out'}</p>
      <p>Tags: {tags.join(', ')}</p>
    </div>
  );
}

function App() {
  return (
    <ProductCard
      name="Mechanical Keyboard"
      price={129.99}
      inStock={true}
      tags={['tech', 'peripherals', 'sale']}
    />
  );
}
Tip

Boolean shorthand

If a prop is a boolean and you want to pass true, you can just write the prop name alone — no ={true} needed.

``jsx // These two lines are identical: <Button disabled={true} /> <Button disabled /> ``

#Props Are Read-Only

Common mistake

Never modify props inside a component

Props flow one direction: from parent to child. A component must never change the props it receives — they are read-only.

```jsx // BAD — mutating a prop function Badge({ label }) { label = label.toUpperCase(); // don't do this! return <span>{label}</span>; }

// GOOD — derive a new value from the prop function Badge({ label }) { const display = label.toUpperCase(); return <span>{display}</span>; } ```

If you need to change something in response to user input, that's the job of state — which is the next lesson.

#Default Props

Sometimes a prop is optional and you want a sensible fallback when it is not provided. You can set default values right in the destructuring, using the = syntax.

Default values let callers omit optional props without breaking the component.
function Avatar({ name, size = 40, shape = 'circle' }) {
  return (
    <img
      src={`/avatars/${name}.png`}
      alt={name}
      width={size}
      height={size}
      style={{ borderRadius: shape === 'circle' ? '50%' : '4px' }}
    />
  );
}

// Uses defaults for size and shape:
<Avatar name="alice" />

// Overrides both defaults:
<Avatar name="bob" size={80} shape="square" />

#Composing Components with Props

The real payoff arrives when you build a small, prop-driven component and then reuse it many times inside a parent. Here is a TeamRoster that renders a list of MemberCard components — each powered by its own props.

One component definition, three different outputs — this is the power of props and composition.
function MemberCard({ name, role, avatarUrl }) {
  return (
    <div className="card">
      <img src={avatarUrl} alt={name} />
      <h3>{name}</h3>
      <span>{role}</span>
    </div>
  );
}

const team = [
  { name: 'Priya Sharma', role: 'Designer', avatarUrl: '/avatars/priya.png' },
  { name: 'Leon Okafor', role: 'Engineer', avatarUrl: '/avatars/leon.png' },
  { name: 'Sara Mills',  role: 'PM',       avatarUrl: '/avatars/sara.png' },
];

function TeamRoster() {
  return (
    <section>
      <h2>Our Team</h2>
      {team.map((member) => (
        <MemberCard key={member.name} {...member} />
      ))}
    </section>
  );
}
Note

The key prop when rendering lists

When you .map() over an array to render components, React needs a key prop on each item so it can track which element is which when the list changes. Use something stable and unique — like an ID or a name — not the array index.

Quick check

What will this component render when used as <Label /> (no props passed)?

Key takeaways

  • Props are the inputs to a component — they are passed as JSX attributes from the parent.
  • Destructure props in the function signature for cleaner, more readable code.
  • Strings use quotes; all other JS values (numbers, booleans, arrays, objects) use curly braces.
  • Props are read-only — a component must never mutate the props it receives.
  • Default values in destructuring let you make props optional without extra logic.
Practice challenges
Test yourself · earn XP
0/4
Predict the output#1

The Label component uses a default prop value. What does this render when used as <Label /> with no props?

predict-output
function Label({ text = 'Default' }) {
  return <span>{text}</span>;
}

// Used as:
<Label />
Fix the bug#2

This code has a bug — what's wrong?

fix-bug
function Badge({ label }) {
  label = label.toUpperCase();
  return <span>{label}</span>;
}
Fill in the blank#3

TeamRoster maps over an array to render one MemberCard per member. React needs one special prop on each mapped element so it can track items across re-renders. Fill in the prop name.

{team.map((member) => (
  <MemberCard ={member.name} {...member} />
))}
Reorder the lines#4

Arrange these lines into a correct ProductCard component that destructures its props and renders the name, formatted price, and stock status.

1
      <p>{inStock ? 'In stock' : 'Sold out'}</p>
2
    <div>
3
    </div>
4
      <h3>{name}</h3>
5
  return (
6
}
7
function ProductCard({ name, price, inStock }) {
8
      <p>${price.toFixed(2)}</p>
9
  );
Your turn
Practice exercise

Build a BookCard component that accepts three props: title (string), author (string), and available (boolean). Render the title in an <h3>, the author in a <p>, and show either 'Available' or 'Checked out' depending on the available prop. Then render at least two <BookCard /> instances in an App component — one available and one not.

Try it live — edit the code and hit Run to see it rendered:

solution.jsx · editable