React FundamentalsPart 3

Props — the Attributes a Parent Hands to a Child

A look at React's Props framed against HTML attributes. How they act like function arguments, destructuring, children, and why the rule 'Props are read-only' exists at all.

At the end of last time I teased “how a parent hands values down to a child when composing components.” That’s exactly Props. It looks easy, yet it’s a prime suspect for making things not work as intended once you start building — and most of that confusion comes from slightly misreading what Props actually are. Today let’s pin that down.


Props are a component’s ‘attributes’

Props is short for Properties — “attributes.” It’s hardly an exaggeration to say the name is the whole story. On the web we’ve been using attributes all along.

<a href="https://...">Link</a>

Here href is an attribute of the a element. You give the tag a property, which decides how that element looks and behaves. In React, a component takes the place of that element. And because a component is a function, attributes are passed like the function’s arguments.

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

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

Writing <Welcome name="Sara" /> means the Welcome function receives { name: "Sara" } as props. The result is <h1>Hello, Sara</h1>. In other words, the things you write as JSX attributes get bundled into a single object and passed to the component function as its argument.


In practice, you pull them out by destructuring

Prefixing everything with props.props.name, props.age — gets tedious, so in practice it’s far more common to destructure just what you need right away.

function Welcome({ name, age }) {
  return <h1>{name}, you're {age}</h1>;
}

The behavior is identical. You’ve simply unpacked the incoming props object right there in the function’s signature. You can give defaults in the same place, too.

function Welcome({ name = "Guest" }) {
  return <h1>Welcome, {name}</h1>;
}

Props are read-only

The single most important rule: a child cannot change the Props it receives. They’re read-only.

function MyComponent({ name }) {
  name = "Another name"; // 🚩 don't do this
  return <h3>{name}</h3>;
}

Why the restriction? If you give ‘ink’ the attribute ‘black’ and define it as ‘black ink,’ that ink can’t turn its own color red on its own. An attribute is an identity the component received from the outside (its parent). If a child changed it freely, the promise the parent made — “this is how you should look” — would break.

This rule ties into React’s big principle, one-way data flow. Data always flows parent → child, top to bottom. Because values flow in only one direction, it’s easier to trace “where on earth did this value change?”, and that’s what makes the ‘predictable screen’ from earlier articles possible.


children — what sits between the tags is also a Prop

Not just attributes: whatever you put between a component’s opening and closing tags is passed as a Prop too. It arrives under the special name children.

function Card({ children }) {
  return <div className="card">{children}</div>;
}

function App() {
  return (
    <Card>
      <h2>Title</h2>
      <p>Body</p>
    </Card>
  );
}

The <h2> and <p> slot right into the {children} spot inside Card. This lets you cleanly separate the outer shell (a card, modal, layout, etc.) from the content that goes inside it.


Let’s not call Props a ‘communication channel’

As we wrap up, one perspective worth correcting. Props are often explained as “the way a parent sends values to a child” — not wrong, but with the order reversed.

The essence of Props is always defining a child component’s attributes. Since the values that define those attributes happen to be handed down by the parent, they end up being used for top-down data passing as well. See them not as “a tool for carrying values” but as “a spec the parent writes for how the child should look,” and the “doesn’t work as intended” moments from the opening drop sharply. The read-only rule feels natural from this view, too.

But a natural question arises here. If Props are values received from outside that can’t be changed, how do we handle a value the component holds itself and that changes over time? That’s exactly the subject of the next article — State.