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:
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:
function Greet({ name, role }) {
return <p>Hello, {name}! You are a {role}.</p>
}
// Usage in JSX:
<Greet name="Alice" role="developer" />A Complete UserCard Example
Here is a UserCard component that accepts multiple props of different types — string, number, boolean, array, and function:
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} |
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:
// 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:
const userData = {
name: 'Carol',
age: 25,
isPremium: true,
skills: ['CSS', 'Design'],
}
// Equivalent to writing name={userData.name} age={userData.age} ...
<UserCard {...userData} onFollow={handleFollow} />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:
// 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