🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
REFERENCEreact

react Documentation

LOADING ENGINE...

Props

AI & DATA SCIENCE // props

Props (short for properties) are read-only inputs passed from a parent component into a child component, used to configure how the child renders and behaves.

Syntax

<ChildComponent name="Ana" age={30} />

Deep Dive Course

Props flow in one direction only, from parent to child, and are passed just like HTML attributes, though any value type can be passed via curly braces, not just strings — a component receives all its props bundled into a single object as its first function argument. Props are strictly read-only from the receiving component's perspective; a component must never modify its own props directly, since React relies on props staying immutable to reliably detect when a re-render is actually necessary.

1Understanding Props

Props flow in one direction only, from parent to child, and are passed just like HTML attributes, though any value type can be passed via curly braces, not just strings — a component receives all its props bundled into a single object as its first function argument. Props are strictly read-only from the receiving component's perspective; a component must never modify its own props directly, since React relies on props staying immutable to reliably detect when a re-render is actually necessary.

💡

Never modify a prop's value directly inside the component that received it — props are meant to be read-only, and mutating one directly can produce confusing, hard-to-track bugs since the parent component remains unaware its data was changed.

editor.html
function Greeting({ name, age }) {
  return <p>{name} is {age} years old.</p>;
}

function App() {
  return <Greeting name="Ana" age={30} />;
}
localhost:3000

2Practical Example

Here is a real-world application of Props showing how it is used in production React code.

editor.html
function Button({ label, onClick }) {
  return <button onClick={onClick}>{label}</button>;
}

function App() {
  const handleClick = () => console.log('Clicked!');
  return <Button label="Submit" onClick={handleClick} />;
}
localhost:3000

3Best Practices

Follow these guidelines when working with Props:

1. Treat every prop as strictly read-only inside the receiving component, copying it into local state first if you need a modifiable version

2. Use destructuring, function MyComponent({ name, age }), to access props cleanly rather than repeatedly writing props.name, props.age

3. Provide default values for optional props, either via default parameters in destructuring or a defaultProps property, so the component behaves sensibly when a prop is omitted

⚠️

Tip: Never modify a prop's value directly inside the component that received it — props are meant to be read-only, and mutating one directly can produce confusing, hard-to-track bugs since the parent component remains unaware its data was changed.

editor.html
function Greeting({ name, age }) {
  return <p>{name} is {age} years old.</p>;
}

function App() {
  return <Greeting name="Ana" age={30} />;
}
localhost:3000

4Default Values for Props

A destructured parameter can specify a default value directly: function Button({ variant = 'primary' }). The default kicks in only when the prop is omitted entirely, or explicitly passed as undefined — passing null does not trigger it, since null is treated as a deliberately provided value.

editor.html
function Button({ variant = 'primary', children }) {
  return <button className={variant}>{children}</button>;
}

<Button>Save</Button>
localhost:3000

5Spreading Props

When a component needs to forward most of its received props unchanged to an underlying element, the spread syntax passes every property of an object as individual props in one line: <input {...inputProps} />. Explicit props listed after the spread override any same-named prop from the spread object.

editor.html
function TextField(props) {
  return <input className="field" {...props} />;
}

<TextField placeholder="Email" type="email" />
localhost:3000

Examples

Example 01Basic Usage
function Greeting({ name, age }) {
  return <p>{name} is {age} years old.</p>;
}

function App() {
  return <Greeting name="Ana" age={30} />;
}
Example 02Advanced Example
function Button({ label, onClick }) {
  return <button onClick={onClick}>{label}</button>;
}

function App() {
  const handleClick = () => console.log('Clicked!');
  return <Button label="Submit" onClick={handleClick} />;
}
Example 03Forwarding Props with Spread and Defaults
function TextField({ variant = 'default', ...rest }) {
  return <input className={variant} {...rest} />;
}

<TextField placeholder="Email" type="email" variant="large" />

Best Practices

  • Treat every prop as strictly read-only inside the receiving component, copying it into local state first if you need a modifiable version
  • Use destructuring, function MyComponent({ name, age }), to access props cleanly rather than repeatedly writing props.name, props.age
  • Provide default values for optional props, either via default parameters in destructuring or a defaultProps property, so the component behaves sensibly when a prop is omitted
  • Use the spread syntax to forward unrelated props to an underlying element, but list explicit overrides after the spread so they always win
  • Remember that a prop explicitly passed as null does not trigger its default value — only an omitted prop or one passed as undefined does

Interview Question

Why does React consider it important that props remain immutable inside the component that receives them?

Hint: Think about how React decides whether a component actually needs to re-render, and what breaks if that assumption doesn't hold.

React's rendering model, and various optimizations like React.memo, rely on the assumption that a component's output is a predictable function of its current props and state — if a component silently mutated a prop it received, the parent component that originally passed that value down would have no way of knowing its data had changed, since it still holds a reference to what it thinks is the same, unmodified object. This breaks the predictable, one-directional data flow React is built around, making it much harder to reason about where a particular piece of data actually changed and why, and can cause optimizations that compare a previous prop value against a new one to work incorrectly, since if the object was mutated in place rather than replaced, both the previous and current references might now point to the very same, already-changed object.

Exercises

MediumPractice using Props in a real scenario.
View Solution
function Greeting({ name, age }) {
  return <p>{name} is {age} years old.</p>;
}

function App() {
  return <Greeting name="Ana" age={30} />;
}

Frequently Asked Questions

Why does React consider it important that props remain immutable inside the component that receives them?

React's rendering model, and various optimizations like React.memo, rely on the assumption that a component's output is a predictable function of its current props and state — if a component silently mutated a prop it received, the parent component that originally passed that value down would have no way of knowing its data had changed, since it still holds a reference to what it thinks is the same, unmodified object. This breaks the predictable, one-directional data flow React is built around, making it much harder to reason about where a particular piece of data actually changed and why, and can cause optimizations that compare a previous prop value against a new one to work incorrectly, since if the object was mutated in place rather than replaced, both the previous and current references might now point to the very same, already-changed object.

Why doesn't passing null to a prop with a destructured default value trigger that default?

JavaScript's default parameter syntax only substitutes the default when the value being destructured is strictly undefined — it's a deliberate, narrow check, not a general 'is this falsy or missing' check. Passing null is treated as the caller explicitly choosing that value on purpose, so it's passed through as null rather than silently replaced. This matters in practice when a prop represents 'no value, on purpose' (like a cleared selection) as null, distinct from 'the caller didn't specify this prop at all' as undefined — the two need different handling if a component's logic cares about that distinction.

Related Functions

statecomponentschildren