Data Flow
Pass data from parent to child in a predictable one-way direction.
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.
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} />;}function User(props) { return ( <h1> {props.name} - {props.age} </h1> );}function User({ name, age }) { return ( <h1> {name} - {age} </h1> );}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} /><User skills={["React", "Python"]} user={{ name: "Sahil", age: 20 }} /><User onClick={handleClick} />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>;}User.defaultProps = { name: "Guest",};Props can move through multiple levels in a component tree.
App ├── Header ├── User │ └── Profilefunction App() { return <User name="Sahil" />;}
function User(props) { return <Profile name={props.name} />;}| Feature | Props | State |
|---|---|---|
| Ownership | Parent | Component |
| Mutability | Immutable | Mutable |
| Purpose | Data passing | Internal 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 behaviorChild triggers itWhen props change, React re-renders the receiving component.
New Props -> Re-render -> New UIEven 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 -> DCommon issues:
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"; // WrongToo 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 propsObjects 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.
Keep these two ideas in mind:
Props = Configuration of a ComponentComponent = Function(props) -> UI