Last updated: 2026-05-06

props = “properties”

Props (short for "properties") are how you pass data into functional components to make them dynamic and reusable. Without props, every component would be hardcoded and only useful in one specific context. With props, you can create a single component that renders different content depending on what data is passed into it.


The Problem Without Props

function ProfileCard() {
  return (
    <div>
      <h2>Wariz</h2>
      <p>React Pro</p>
    </div>
  );
}

This is hardcoded. It can only ever display "Wariz" and "React Pro." Not scalable.


Passing and Receiving Props

Props are passed to a component like HTML attributes and received inside the function as a plain JavaScript object. You access individual values using dot notation:

ProfileCard.jsx

function ProfileCard(props) {
  return (
    <div>
      <h2>{props.name}</h2>
      <p>{props.skill}</p>
    </div>
  );
}

export default ProfileCard;

App.jsx

import ProfileCard from "./ProfileCard";

function App() {
  return (
    <div>
      <h1>React Props Practice</h1>
      <ProfileCard name="Wariz" skill="React Pro" />
      <ProfileCard name="Ada" skill="UI Designer" />
      <ProfileCard name="Aliyu" skill="Backend Dev" />
    </div>
  );
}

export default App;

One component, three different outputs — no duplication.


Destructuring Props

The most common pattern in modern React is to destructure props directly in the function signature. Instead of receiving the full props object and accessing props.name, you pull out the values you need immediately:

// Instead of this:
function ProfileCard(props) {
  return <h2>{props.name}</h2>;
}

// Write this:
function ProfileCard({ name, skill }) {
  return (
    <div>
      <h2>{name}</h2>
      <p>{skill}</p>
    </div>
  );
}

Both are equivalent — destructuring is just cleaner and more readable. You will see this pattern in almost all modern React code.


Default Prop Values

You can assign default values to props using JavaScript's default parameter syntax. If the parent component doesn't pass a value for that prop, the default is used instead.

function ProfileCard({ name = "Guest", skill = "Unknown" }) {
  return (
    <div>
      <h2>{name}</h2>
      <p>{skill}</p>
    </div>
  );
}

// Used without props:
<ProfileCard />
// Renders: Guest / Unknown

// Used with props:
<ProfileCard name="Wariz" skill="React Pro" />
// Renders: Wariz / React Pro

The children Prop

React has a special built-in prop called children that represents whatever is placed between a component's opening and closing tags. This is one of the most commonly used props in React and is what makes wrapper or layout components possible.

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

Using it:

<Card>
  <h2>Wariz</h2>
  <p>React Developer</p>
</Card>

Whatever is placed between <Card> and </Card> becomes children inside the component. The Card component doesn't need to know what's inside — it just wraps and styles it.


Typing Props with TypeScript

Since props are just a JavaScript object, they can be typed in TypeScript using an interface or type alias. This ensures the correct data is always passed and provides autocomplete in your editor.

interface ProfileCardProps {
  name: string;
  skill: string;
}

function ProfileCard({ name, skill }: ProfileCardProps) {
  return (
    <div>
      <h2>{name}</h2>
      <p>{skill}</p>
    </div>
  );
}

If a required prop is missing or the wrong type is passed, TypeScript will flag it immediately — before the code even runs.


Props Are Read-Only

A component can never modify the props it receives. Props flow one way — from parent to child — and are strictly read-only inside the receiving component. If you need to change data based on user interaction, that is the job of state, not props.

function ProfileCard({ name }) {
  name = "Someone else"; // ❌ Never do this — props must not be mutated
  return <h2>{name}</h2>;
}

Quick Rules

  • If your component uses no external data, no need for props.
  • If it needs data from a parent, accept props as a parameter.
  • Always use destructuring for cleaner, more readable code.
  • Always type your props with TypeScript in TypeScript projects.
  • Never mutate props — use state for data that needs to change.