ReactPassing Props to Components

Passing Props to Components

Props — short for properties — are the mechanism React uses to pass data from a parent component into a child component. If components are functions, then props are their parameters. You pass props in JSX the same way you write HTML attributes, and you read them inside the function body.

Understanding props is fundamental to React development. Every time you place a component in JSX you are configuring it through props. A <Button color="primary" label="Save" /> tells the Button component exactly what to render without Button needing to know where it lives in the tree.

Props Are Like Function Parameters

Consider a plain JavaScript function that greets a user:

JS
function greet(name, role) {
  return `Hello, ${name}! You are a ${role}.`
}

greet('Alice', 'developer') // "Hello, Alice! You are a developer."

A React component works exactly the same way — except instead of returning a string it returns JSX, and instead of calling it with () you use JSX tag syntax:

JSX
function Greet({ name, role }) {
  return <p>Hello, {name}! You are a {role}.</p>
}

// Usage in JSX:
<Greet name="Alice" role="developer" />
Note
React passes all JSX attributes to your component as a single object called `props`. `<Greet name="Alice" />` is equivalent to calling `Greet({ name: 'Alice' })`.
A Complete UserCard Example

Here is a UserCard component that accepts multiple props of different types — string, number, boolean, array, and function:

JSX
function UserCard({ name, age, isPremium, skills, onFollow }) {
  return (
    <div className="card">
      <h2>{name}</h2>
      <p>Age: {age}</p>
      {isPremium && <span className="badge">Premium</span>}
      <ul>
        {skills.map((skill) => (
          <li key={skill}>{skill}</li>
        ))}
      </ul>
      <button onClick={onFollow}>Follow</button>
    </div>
  )
}

// Parent component providing all props:
function App() {
  function handleFollow() {
    alert('Followed!')
  }

  return (
    <UserCard
      name="Alice Chen"
      age={28}
      isPremium={true}
      skills={['React', 'TypeScript', 'GraphQL']}
      onFollow={handleFollow}
    />
  )
}
Prop Types in JSX Syntax

The JSX syntax for passing props varies depending on the value type:

Type

JSX syntax

Example

String

Quote delimiters

name="Alice"

Number

Curly braces

age={28}

Boolean (true)

Attribute only

isPremium

Boolean (false)

Curly braces

isPremium={false}

Array

Curly braces

skills={['React', 'TS']}

Object

Curly braces

style={{ color: 'red' }}

Function

Curly braces

onClick={handleClick}

Variable

Curly braces

value={myVar}

Tip
A boolean prop written without a value defaults to `true`. `<Button disabled />` is the same as `<Button disabled={true} />`.
Dynamic vs Static Props

Props can be static (hardcoded values) or dynamic (variables, expressions, or function return values). In practice most real applications use dynamic props:

JSX
// Static props — values are literals
<UserCard name="Alice" age={28} isPremium />

// Dynamic props — values come from variables or expressions
const user = { name: 'Bob', age: 32, premium: false }
const userSkills = ['Vue', 'Node.js']

<UserCard
  name={user.name}
  age={user.age}
  isPremium={user.premium}
  skills={userSkills}
  onFollow={() => followUser(user.name)}
/>
Spreading an Object as Props

When you have an object whose keys match prop names, you can spread it directly instead of typing each prop individually:

JSX
const userData = {
  name: 'Carol',
  age: 25,
  isPremium: true,
  skills: ['CSS', 'Design'],
}

// Equivalent to writing name={userData.name} age={userData.age} ...
<UserCard {...userData} onFollow={handleFollow} />
Warning
Spread props are convenient but can make it hard to see what a component actually receives. Use them when the shapes match intentionally (e.g. forwarding props to a DOM element), and prefer explicit props when authoring new components.
Props Are One-Way

Data flows in one direction in React: from parent to child. A parent passes props down; a child reads them. The child cannot push data back up by modifying a prop — props are read-only from the child's perspective.

This one-way data flow makes applications easier to reason about. When something goes wrong you always know where data came from: follow the props up to the parent that passed them. The standard pattern for a child to communicate upward is for the parent to pass a callback function as a prop — the child calls it when something happens:

JSX
// Parent controls the data; child calls back to report events
function Parent() {
  const [count, setCount] = useState(0)

  return <Counter value={count} onIncrement={() => setCount(count + 1)} />
}

function Counter({ value, onIncrement }) {
  return (
    <div>
      <p>Count: {value}</p>
      <button onClick={onIncrement}>+1</button>
    </div>
  )
}
  • Props flow down — parent → child, never the other way directly

  • Callbacks flow up — a child calls a function prop to notify its parent

  • Props are snapshots — each render receives the prop values at that moment in time

  • Any JavaScript value is a valid prop — strings, numbers, booleans, objects, arrays, functions, even other components