Skip to content

Props

Props (short for properties) are inputs passed from a parent component to a child component. They make components configurable and reusable. In practice, props are one of the most important mechanisms in React because they define how data flows through the component tree.

graph TD P["Parent Component"] -->|props| C["Child Component"] C --> U["Rendered UI"]

Data Flow

Pass data from parent to child in a predictable one-way direction.

Reusability

Reuse the same component with different prop values.

Dynamic UI

Render different output based on changing inputs.

function App() {
return <User name="Sahil" age={20} />;
}

Props are immutable inside the child component. A child must never mutate them. If a value needs to change, the parent should update and pass new props.

function User(props) {
props.name = "Changed"; // Wrong: never mutate props
}

React follows unidirectional data flow: parent to child.

Parent -> Child (one-way)

React props can hold almost any JavaScript value.

<User name="Sahil" age={20} isAdmin={true} />

Class components access props with this.props.

class User extends React.Component {
render() {
return <h1>{this.props.name}</h1>;
}
}

Default values are used when a prop is missing.

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

Props can move through multiple levels in a component tree.

App
├── Header
├── User
│ └── Profile
function App() {
return <User name="Sahil" />;
}
function User(props) {
return <Profile name={props.name} />;
}
graph LR A["App"] -->|name| B["User"] B -->|name| C["Profile"]
FeaturePropsState
OwnershipParentComponent
MutabilityImmutableMutable
PurposeData passingInternal logic

props.children contains everything placed between opening and closing tags of a component.

function Card(props) {
return <div>{props.children}</div>;
}
<Card>
<h1>Hello</h1>
</Card>
<Card>
props.children = <h1>Hello</h1>

Props are often used in conditional rendering logic.

function User({ isLoggedIn }) {
return <h1>{isLoggedIn ? "Welcome" : "Please Login"}</h1>;
}

Spread props are concise and common for forwarding related values.

const user = { name: "Sahil", age: 20 };
<User {...user} />;

Equivalent to:

<User name="Sahil" age={20} />

Function props allow child components to trigger parent-controlled behavior.

function Parent() {
function handleClick() {
console.log("Clicked");
}
return <Child onClick={handleClick} />;
}
function Child({ onClick }) {
return <button onClick={onClick}>Click</button>;
}
Parent controls behavior
Child triggers it

When props change, React re-renders the receiving component.

New Props -> Re-render -> New UI

Even when output looks the same, render work may still happen unless you optimize intentionally.

The key prop helps React match list items correctly across updates.

items.map((item) => <li key={item.id}>{item.name}</li>);

Keys should be stable, unique, and not change between renders to prevent unnecessary re-renders.

Prop drilling happens when props are passed through many intermediate components.

App -> A -> B -> C -> D

Common issues:

  • Verbose component wiring.
  • Harder maintenance as the tree grows.

Composition is preferred over inheritance in React.

function Layout({ header, content }) {
return (
<div>
{header}
{content}
</div>
);
}

A render prop is a function passed as a prop to control rendering output.

function DataProvider({ render }) {
const data = "Hello";
return render(data);
}
<DataProvider render={(data) => <h1>{data}</h1>} />

An HOC is a function that takes a component and returns an enhanced component.

function withLogger(Component) {
return function Wrapped(props) {
console.log(props);
return <Component {...props} />;
};
}

PropTypes is an older but still useful runtime validation approach in JavaScript React projects.

import PropTypes from "prop-types";
User.propTypes = {
name: PropTypes.string,
age: PropTypes.number,
};
props.name = "Hack"; // Wrong

Too many props can make component APIs difficult to understand.

Avoid forwarding data that a component does not need.

React compares prop references shallowly, especially in memoized components.

Old props vs New props

Objects and arrays are compared by reference, not deep content.

<User data={{ name: "Sahil" }} />

This creates a new object each render, which can trigger avoidable re-renders.

React.PureComponent performs shallow prop/state comparison to skip unnecessary re-renders.

class User extends React.PureComponent {}

When a parent re-renders, it generates new props for its children. React then reconciles the child components with the new props and updates the DOM if necessary.

graph TD A["Parent Re-renders"] --> B["New Props Generated"] B --> C["Child Receives Props"] C --> D["Reconciliation"] D --> E["DOM Updated If Needed"]

Keep these two ideas in mind:

Props = Configuration of a Component
Component = Function(props) -> UI