React Tutorial 0/120 lessons ~6 min read Lesson 19

    Props in React

    Props in React explains parent-to-child data flow, prop values, destructuring, callbacks, children, composition, immutability, prop drilling, forwarding, and props versus state.

    Course progress0%
    Focus
    71 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Props — short for properties — are one of the most important concepts in React.

    Props allow a parent component to pass data and behavior to a child component.

    The simplest mental model is:

    text
    Parent Component
    │
    │ props
    ▼
    Child Component
    │
    ▼
    UI

    For example:

    jsx
    function Greeting({ name }) {
    return <h1>Hello, {name}</h1>;
    }
    function App() {
    return <Greeting name="Jagannath" />;
    }

    Here, App passes the prop name to Greeting.

    Learning Objectives

    By the end of this lesson, you will understand:

    1. What props are
    2. Why props are needed
    3. Passing props
    4. Receiving props
    5. Multiple props
    6. Props with numbers and booleans
    7. Props with objects and arrays
    8. Destructuring props
    9. Default values
    10. Passing functions as props
    11. children props
    12. Props and component composition
    13. One-way data flow
    14. Props immutability
    15. Props vs state
    16. Common mistakes
    17. Best practices
    18. Practical examples
    19. Interview questions

    What Are Props?

    Props are inputs passed into a React component.

    Consider:

    jsx
    <Greeting name="Rahul" />

    Here:

    text
    Greeting
    ↑
    name="Rahul"

    name is a prop.

    The child component can access it:

    jsx
    function Greeting(props) {
    return <h1>Hello, {props.name}</h1>;
    }

    Props Are Like Function Arguments

    This is one of the best ways to understand props.

    Normal JavaScript:

    javascript
    function greet(name) {
    return `Hello, ${name}`;
    }
    greet("Rahul");

    React:

    jsx
    function Greeting(props) {
    return <h1>Hello, {props.name}</h1>;
    }
    <Greeting name="Rahul" />;

    Think:

    text
    JavaScript function
    ↓
    argument
    ↓
    React component
    ↓
    props

    A component receives props much like a function receives arguments.

    Passing a Prop

    The parent passes a prop using an attribute-like syntax:

    jsx
    <Greeting name="Rahul" />

    Here:

    text
    name
    ↓
    prop name
    "Rahul"
    ↓
    prop value

    Receiving Props

    The child receives an object containing the props.

    jsx
    function Greeting(props) {
    return (
    <h1>
    Hello, {props.name}
    </h1>
    );
    }

    If you render:

    jsx
    <Greeting name="Rahul" />

    React provides conceptually:

    javascript
    props = {
    name: "Rahul"
    };

    So:

    jsx
    props.name

    returns:

    text
    Rahul

    Multiple Props

    A component can receive many props.

    jsx
    function Student(props) {
    return (
    <div>
    <h2>{props.name}</h2>
    <p>{props.course}</p>
    <p>{props.city}</p>
    </div>
    );
    }

    Use it:

    jsx
    <Student
    name="Rahul"
    course="React"
    city="Hyderabad"
    />

    Conceptually:

    javascript
    props = {
    name: "Rahul",
    course: "React",
    city: "Hyderabad"
    };

    Destructuring Props

    Instead of:

    jsx
    function Student(props) {
    return (
    <div>
    <h2>{props.name}</h2>
    <p>{props.course}</p>
    </div>
    );
    }

    You can destructure:

    jsx
    function Student({ name, course }) {
    return (
    <div>
    <h2>{name}</h2>
    <p>{course}</p>
    </div>
    );
    }

    This is extremely common in modern React.

    Understanding the Destructuring

    This:

    jsx
    function Student({ name, course }) {

    is essentially shorthand for accessing:

    jsx
    props.name
    props.course

    Compare:

    jsx
    function Student(props) {
    return <h2>{props.name}</h2>;
    }

    with:

    jsx
    function Student({ name }) {
    return <h2>{name}</h2>;
    }

    Both are valid.

    Passing Strings

    Strings can be passed directly:

    jsx
    <Greeting name="Rahul" />

    The value is a string.

    Another example:

    jsx
    <Course title="React Fundamentals" />

    Passing Numbers

    For numbers, use curly braces:

    jsx
    <Course price={4999} />

    Then:

    jsx
    function Course({ price }) {
    return <p>Price: ₹{price}</p>;
    }

    Result:

    text
    Price: ₹4999

    Why Curly Braces for Numbers?

    Compare:

    jsx
    <Course price="4999" />

    and:

    jsx
    <Course price={4999} />

    The first passes:

    text
    "4999"

    as a string.

    The second passes:

    text
    4999

    as a number.

    This distinction can matter when performing calculations.

    Passing Booleans

    You can pass a boolean:

    jsx
    <User isAdmin={true} />

    or:

    jsx
    <User isAdmin={false} />

    You can also use shorthand:

    jsx
    <User isAdmin />

    which is equivalent to:

    jsx
    <User isAdmin={true} />

    Using Boolean Props

    jsx
    function User({ isAdmin }) {
    return (
    <div>
    {isAdmin
    ? <p>Administrator</p>
    : <p>Regular User</p>}
    </div>
    );
    }

    Use:

    jsx
    <User isAdmin />

    Passing Arrays

    Props can contain arrays.

    jsx
    const courses = [
    "React",
    "JavaScript",
    "Node.js"
    ];
    function CourseList({ courses }) {
    return (
    <ul>
    {courses.map(course => (
    <li key={course}>
    {course}
    </li>
    ))}
    </ul>
    );
    }

    Use:

    jsx
    <CourseList courses={courses} />

    Passing Objects

    Props can contain objects too.

    jsx
    const user = {
    name: "Rahul",
    age: 25,
    city: "Hyderabad"
    };

    Pass it:

    jsx
    <User user={user} />

    Receive it:

    jsx
    function User({ user }) {
    return (
    <div>
    <h2>{user.name}</h2>
    <p>{user.age}</p>
    <p>{user.city}</p>
    </div>
    );
    }

    Passing Objects Directly

    You can also write:

    jsx
    <User
    user={{
    name: "Rahul",
    age: 25
    }}
    />

    Notice the double curly braces:

    jsx
    user={{ ... }}

    The outer {} means:

    Evaluate JavaScript.

    The inner {} is:

    A JavaScript object.

    Passing Functions as Props

    This is a very important React pattern.

    A parent can pass a function to a child.

    jsx
    function App() {
    function handleClick() {
    console.log("Clicked");
    }
    return (
    <Button onClick={handleClick} />
    );
    }

    The child:

    jsx
    function Button({ onClick }) {
    return (
    <button onClick={onClick}>
    Click Me
    </button>
    );
    }

    The flow is:

    text
    App
    │
    │ onClick function
    ▼
    Button
    │
    │ user clicks
    ▼
    Parent function executes

    Why Pass Functions?

    This allows a child component to communicate an event back to its parent.

    For example:

    jsx
    function App() {
    function handleDelete() {
    console.log("Delete requested");
    }
    return (
    <DeleteButton
    onDelete={handleDelete}
    />
    );
    }

    Child:

    jsx
    function DeleteButton({ onDelete }) {
    return (
    <button onClick={onDelete}>
    Delete
    </button>
    );
    }

    The child doesn't need to know what deletion actually does.

    It simply says:

    The user requested deletion.

    The parent decides what happens.

    Passing Arguments Through Functions

    Suppose the parent has:

    jsx
    function App() {
    function handleDelete(id) {
    console.log("Deleting", id);
    }
    return (
    <button
    onClick={() => handleDelete(101)}
    >
    Delete
    </button>
    );
    }

    A child can do the same:

    jsx
    function DeleteButton({ onDelete, id }) {
    return (
    <button
    onClick={() => onDelete(id)}
    >
    Delete
    </button>
    );
    }

    Use:

    jsx
    <DeleteButton
    id={101}
    onDelete={handleDelete}
    />

    Props Are Read-Only

    This is one of the most important rules:

    A component should not modify its props.

    Suppose:

    jsx
    function User({ name }) {
    // ❌ Don't do this
    name = "John";
    return <h1>{name}</h1>;
    }

    Props should be treated as immutable inputs.

    Instead, if the value needs to change, the parent should provide a new prop value, or the component should use its own state where appropriate.

    One-Way Data Flow

    React follows a primarily one-way data flow model.

    text
    Parent
    │
    │ props
    ▼
    Child

    Data flows downward.

    For example:

    text
    App
    ↓
    UserProfile
    ↓
    Avatar

    App can provide data to UserProfile.

    UserProfile can provide data to Avatar.

    Data Does Not Automatically Flow Up

    Suppose:

    text
    Parent
    ↓
    Child

    The child cannot simply modify the parent's props.

    Instead, the parent can pass a function:

    text
    Parent
    │
    ├── data ↓
    │
    └── function ↓
    │
    ▼
    Child
    │
    └── calls function
    │
    ▼
    Parent

    This pattern is often called lifting state up when state is moved to a common parent.

    Example: Child-to-Parent Communication

    jsx
    function App() {
    function handleMessage(message) {
    console.log(message);
    }
    return (
    <Child
    onMessage={handleMessage}
    />
    );
    }

    Child:

    jsx
    function Child({ onMessage }) {
    return (
    <button
    onClick={() =>
    onMessage("Hello Parent")
    }
    >
    Send Message
    </button>
    );
    }

    The child isn't changing parent data directly.

    It is invoking a function supplied by the parent.

    Props and `children`

    One special prop is:

    jsx
    children

    For example:

    jsx
    <Card>
    <h2>React</h2>
    <p>Learn React.</p>
    </Card>

    The content inside <Card> becomes the children prop.

    Receiving `children`

    jsx
    function Card({ children }) {
    return (
    <article className="card">
    {children}
    </article>
    );
    }

    This makes the component reusable.

    Why `children` Is Powerful

    You can create a reusable layout:

    jsx
    function Panel({ children }) {
    return (
    <section className="panel">
    {children}
    </section>
    );
    }

    Then:

    jsx
    <Panel>
    <h2>Profile</h2>
    <p>Welcome back.</p>
    </Panel>

    Or:

    jsx
    <Panel>
    <CourseList />
    </Panel>

    The Panel doesn't need to know what its content is.

    Props Can Contain JSX

    Props aren't limited to primitive values.

    You can pass JSX:

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

    Use:

    jsx
    <Layout
    header={<h1>My Website</h1>}
    />

    This is another form of composition.

    Props Can Contain Components

    You can also pass a component reference.

    For example:

    jsx
    function Layout({ Header }) {
    return (
    <div>
    <Header />
    </div>
    );
    }

    Use:

    jsx
    <Layout Header={MyHeader} />

    This pattern is useful in some advanced component architectures.

    Default Prop Values

    You can provide defaults through JavaScript parameter defaults:

    jsx
    function Greeting({
    name = "Guest"
    }) {
    return (
    <h1>
    Hello, {name}
    </h1>
    );
    }

    If you write:

    jsx
    <Greeting />

    the result is:

    text
    Hello, Guest

    Default Values With Multiple Props

    jsx
    function ProductCard({
    name = "Unknown Product",
    price = 0,
    inStock = false
    }) {
    return (
    <article>
    <h2>{name}</h2>
    <p>₹{price}</p>
    <p>
    {inStock
    ? "In Stock"
    : "Out of Stock"}
    </p>
    </article>
    );
    }

    Props and State

    Props and state are related but different.

    Props

    Props are:

    text
    Passed from parent
    ↓
    Child receives

    State

    State belongs to the component:

    text
    Component
    ↓
    Own state

    Props vs State

    PropsState
    Passed into componentManaged by component
    Read-only from child perspectiveCan be updated
    Usually controlled by parentManaged by component or other state owner
    Used to configure componentsUsed for changing data/UI
    Flows downwardChanges trigger re-render

    Example:

    jsx
    function Counter({ initialCount }) {
    const [count, setCount] =
    useState(initialCount);
    // ...
    }

    Here:

    text
    initialCount → prop
    count → state

    Props Can Initialize State

    For example:

    jsx
    function Counter({ initialCount }) {
    const [count, setCount] =
    useState(initialCount);
    return (
    <button
    onClick={() =>
    setCount(count + 1)
    }
    >
    {count}
    </button>
    );
    }

    The parent controls the initial value:

    jsx
    <Counter initialCount={10} />

    After initialization, count is local state.

    Be careful: changing initialCount later does not automatically mean the existing state should be reset. This distinction is important and will become clearer when learning state and effects.

    Props Are Not Automatically State

    Suppose:

    jsx
    function User({ name }) {
    return <h1>{name}</h1>;
    }

    name is a prop.

    You don't need:

    jsx
    const [name, setName] = useState(...);

    unless the component actually needs independently changing local state.

    Don't turn every prop into state unnecessarily.

    Prop Drilling

    Sometimes data needs to travel through several components.

    For example:

    text
    App
    ↓
    Layout
    ↓
    Sidebar
    ↓
    UserProfile

    If only UserProfile needs the user data, you might have:

    jsx
    <App user={user}>
    <Layout user={user}>
    <Sidebar user={user}>
    <UserProfile user={user} />
    </Sidebar>
    </Layout>
    </App>

    Passing props through components that don't use them is called prop drilling.

    Is Prop Drilling Always Bad?

    No.

    For a small component tree:

    text
    Parent
    ↓
    Child
    ↓
    Grandchild

    passing props explicitly can be the simplest and clearest solution.

    You shouldn't introduce Context or another state-management solution just because props pass through two or three components.

    When Prop Drilling Becomes a Problem

    It can become inconvenient when:

    text
    App
    ↓
    Layout
    ↓
    Page
    ↓
    Section
    ↓
    Card
    ↓
    Button

    and every layer passes the same data even though most layers don't need it.

    At that point, alternatives such as Context may be appropriate.

    Props and Referential Values

    Props can contain objects and functions.

    For example:

    jsx
    <User
    user={user}
    onUpdate={handleUpdate}
    />

    The values aren't necessarily simple primitives.

    This becomes important when studying:

    text
    Memoization
    React.memo
    useMemo
    useCallback

    because object and function references can affect whether components re-render.

    Don't worry about optimization yet—first understand basic props.

    Props Are Inputs to Rendering

    A useful mental model:

    text
    Props
    │
    ▼
    Functional Component
    │
    ▼
    JSX
    │
    ▼
    UI

    If the parent supplies different props:

    text
    New props
    ↓
    Component renders with new inputs
    ↓
    UI can change

    Example: Dynamic Course Card

    Let's create a reusable component.

    jsx
    function CourseCard({
    title,
    instructor,
    price,
    level
    }) {
    return (
    <article className="course-card">
    <h2>{title}</h2>
    <p>
    Instructor: {instructor}
    </p>
    <p>
    Level: {level}
    </p>
    <strong>
    ₹{price}
    </strong>
    </article>
    );
    }

    Use it multiple times:

    jsx
    function App() {
    return (
    <main>
    <CourseCard
    title="React Fundamentals"
    instructor="John"
    price={4999}
    level="Beginner"
    />
    <CourseCard
    title="Advanced React"
    instructor="Sarah"
    price={7999}
    level="Advanced"
    />
    </main>
    );
    }

    Same component.

    Different data.

    That's one of the major benefits of props.

    Props Make Components Reusable

    Without props, you might write:

    jsx
    function ReactCourse() {
    return <h2>React Fundamentals</h2>;
    }
    function JavaCourse() {
    return <h2>Java Fundamentals</h2>;
    }

    With props:

    jsx
    function Course({ title }) {
    return <h2>{title}</h2>;
    }

    Then:

    jsx
    <Course title="React Fundamentals" />
    <Course title="Java Fundamentals" />

    One component can handle many cases.

    Props and Component Configuration

    Think of props as configuration.

    For example:

    jsx
    <Button
    variant="primary"
    size="large"
    disabled={false}
    />

    The Button component receives configuration:

    text
    variant
    size
    disabled

    and uses those inputs to determine its UI.

    A Reusable Button

    jsx
    function Button({
    children,
    variant = "primary",
    disabled = false,
    onClick
    }) {
    return (
    <button
    className={`button ${variant}`}
    disabled={disabled}
    onClick={onClick}
    >
    {children}
    </button>
    );
    }

    Use:

    jsx
    <Button variant="primary">
    Save
    </Button>

    or:

    jsx
    <Button
    variant="danger"
    onClick={handleDelete}
    >
    Delete
    </Button>

    This is component design through props.

    Props and Composition

    Props don't only make components configurable.

    They also enable composition.

    For example:

    jsx
    function Card({ children }) {
    return (
    <div className="card">
    {children}
    </div>
    );
    }

    Now:

    jsx
    <Card>
    <h2>Course</h2>
    <p>React Fundamentals</p>
    </Card>

    The parent decides what goes inside the card.

    Props Are Data, Not Commands

    A good way to think about props:

    text
    Props = inputs/configuration

    For example:

    jsx
    <Product
    name="Laptop"
    price={70000}
    available
    />

    These describe the product.

    A function prop:

    jsx
    <Product onBuy={handleBuy} />

    provides behavior the child can trigger.

    Naming Props

    Use meaningful names.

    Good:

    jsx
    <User
    name="Rahul"
    avatarUrl="/avatar.jpg"
    isAdmin
    />

    Less clear:

    jsx
    <User
    x="Rahul"
    img="/avatar.jpg"
    flag
    />

    Clear prop names make components easier to understand and use.

    Boolean Naming

    Boolean props often use names that clearly express a condition:

    jsx
    isActive
    isLoading
    isDisabled
    hasPermission
    showHeader

    For example:

    jsx
    <Button
    isDisabled={true}
    />

    or, depending on the API:

    jsx
    <Button
    disabled
    />

    Choose names that clearly communicate meaning.

    Avoid Excessive Props

    A component with:

    jsx
    <Component
    a={...}
    b={...}
    c={...}
    d={...}
    e={...}
    f={...}
    g={...}
    h={...}
    i={...}
    />

    may indicate that the component has too many responsibilities or that its API needs reconsideration.

    This isn't an absolute rule—complex components can legitimately have many inputs—but keep component APIs understandable.

    Instead of:

    jsx
    <User
    name={name}
    age={age}
    city={city}
    avatar={avatar}
    />

    sometimes an object is appropriate:

    jsx
    <User user={user} />

    Then:

    jsx
    function User({ user }) {
    return (
    <h2>
    {user.name}
    </h2>
    );
    }

    Neither approach is universally better.

    Choose based on clarity and component API design.

    Don't Mutate Objects Received Through Props

    Suppose:

    jsx
    function User({ user }) {
    // ❌ Avoid
    user.name = "John";
    return <h2>{user.name}</h2>;
    }

    The child should not mutate an object it received through props.

    If data needs to change, use an appropriate state owner and create updated values.

    Props and Spread Syntax

    You may encounter:

    jsx
    const userProps = {
    name: "Rahul",
    age: 25,
    city: "Hyderabad"
    };
    <User {...userProps} />

    This passes the object's properties as individual props.

    Equivalent conceptually to:

    jsx
    <User
    name="Rahul"
    age={25}
    city="Hyderabad"
    />

    Receiving Spread Props

    You may also see:

    jsx
    function User(props) {
    return <Profile {...props} />;
    }

    This forwards props.

    However, don't use prop spreading everywhere automatically.

    Explicit props can make component interfaces easier to understand:

    jsx
    <Profile
    name={name}
    age={age}
    />

    Prop Forwarding

    Sometimes a wrapper component forwards certain props:

    jsx
    function Button({ children, ...rest }) {
    return (
    <button {...rest}>
    {children}
    </button>
    );
    }

    Now:

    jsx
    <Button
    type="submit"
    disabled
    >
    Save
    </Button>

    The remaining props are forwarded to the <button>.

    This is useful for reusable UI components, but should be done intentionally.

    Props and DOM Attributes

    Be careful when forwarding arbitrary props to DOM elements.

    For example, custom component props may not belong on native HTML elements.

    A component might receive:

    jsx
    <Button variant="primary" />

    You may not want:

    jsx
    <button variant="primary">

    unless variant is intentionally represented as a valid attribute/data attribute.

    Instead, the component can use variant to determine its class or behavior.

    A Complete Example

    jsx
    function ProductCard({
    name,
    price,
    imageUrl,
    inStock,
    onBuy
    }) {
    return (
    <article className="product-card">
    <img
    src={imageUrl}
    alt={name}
    />
    <h2>{name}</h2>
    <p>
    ₹{price}
    </p>
    <button
    disabled={!inStock}
    onClick={onBuy}
    >
    {inStock
    ? "Buy Now"
    : "Out of Stock"}
    </button>
    </article>
    );
    }

    Parent:

    jsx
    function App() {
    function handleBuy() {
    console.log("Product purchased");
    }
    return (
    <ProductCard
    name="Banarasi Saree"
    price={4999}
    imageUrl="/saree.jpg"
    inStock={true}
    onBuy={handleBuy}
    />
    );
    }

    Here the props include:

    text
    name → string
    price → number
    imageUrl → string
    inStock → boolean
    onBuy → function

    Complete Data Flow

    The example above demonstrates:

    text
    App
    │
    ┌───────────┴───────────┐
    │ │
    Data Functions
    │ │
    └───────────┬───────────┘
    ↓
    ProductCard
    │
    ▼
    JSX
    │
    ▼
    UI
    │
    │ user clicks
    ▼
    onBuy()
    │
    ▼
    App

    This is the fundamental React data-flow pattern.

    Props vs HTML Attributes

    This:

    jsx
    <img src="/logo.png" />

    uses an HTML/DOM property.

    This:

    jsx
    <User name="Rahul" />

    uses a custom component prop.

    The syntax looks similar, but React components can define their own APIs through props.

    Props vs Parameters

    Consider:

    jsx
    function Greeting({ name }) {
    return <h1>Hello {name}</h1>;
    }

    The function parameter:

    jsx
    { name }

    is derived from the component's props object.

    When you write:

    jsx
    <Greeting name="Rahul" />

    React supplies the corresponding props.

    Props Are Immutable From the Child's Perspective

    This phrase is worth remembering:

    Props are read-only inputs.

    The parent can render:

    jsx
    <Greeting name="Rahul" />

    and later:

    jsx
    <Greeting name="Amit" />

    The child receives the new value when React renders it with new props.

    The child doesn't modify:

    jsx
    props.name

    to change the parent.

    Common Mistake: Forgetting Curly Braces for Variables

    Suppose:

    jsx
    const name = "Rahul";

    Incorrect:

    jsx
    <Greeting name="name" />

    This passes the literal string:

    text
    "name"

    Correct:

    jsx
    <Greeting name={name} />

    This passes:

    text
    "Rahul"

    Common Mistake: Passing a Number as a String

    Incorrect if you need a number:

    jsx
    <Course price="4999" />

    Correct:

    jsx
    <Course price={4999} />

    Otherwise:

    jsx
    price + 100

    may behave differently because the value is a string.

    Common Mistake: Mutating Props

    Avoid:

    jsx
    function User({ user }) {
    user.name = "John";
    }

    Treat props as immutable.

    Common Mistake: Turning Every Prop Into State

    Avoid unnecessarily doing:

    jsx
    function User({ name }) {
    const [userName, setUserName] =
    useState(name);
    return <h1>{userName}</h1>;
    }

    If you simply need to display the prop:

    jsx
    function User({ name }) {
    return <h1>{name}</h1>;
    }

    is better.

    Common Mistake: Passing the Result Instead of the Function

    Suppose:

    jsx
    function handleClick() {
    console.log("Clicked");
    }

    Usually:

    jsx
    <Button onClick={handleClick} />

    Not:

    jsx
    <Button onClick={handleClick()} />

    The latter executes the function during rendering.

    Common Mistake: Confusing `children`

    Given:

    jsx
    <Card>
    <h2>Hello</h2>
    </Card>

    the child content is available as:

    jsx
    function Card({ children }) {
    return children;
    }

    It isn't a prop named content unless you explicitly pass:

    jsx
    <Card content={<h2>Hello</h2>} />

    Best Practices

    1. Treat props as read-only.

    2. Give props meaningful names.

    3. Keep component APIs understandable.

    4. Use destructuring when it improves readability.

    5. Don't duplicate props into state unnecessarily.

    6. Use function props for child-to-parent communication.

    7. Use children for composition.

    8. Keep data flow explicit.

    9. Avoid unnecessary prop drilling.

    10. Don't optimize props prematurely.

    Practical Exercise

    Create a:

    text
    StudentCard

    component that accepts:

    text
    name
    course
    progress
    isActive

    Usage:

    jsx
    <StudentCard
    name="Rahul"
    course="React"
    progress={75}
    isActive={true}
    />

    Display:

    text
    Rahul
    React
    Progress: 75%
    Active

    Solution

    jsx
    function StudentCard({
    name,
    course,
    progress,
    isActive
    }) {
    return (
    <article>
    <h2>{name}</h2>
    <p>
    Course: {course}
    </p>
    <p>
    Progress: {progress}%
    </p>
    <p>
    {isActive
    ? "Active"
    : "Inactive"}
    </p>
    </article>
    );
    }

    Advanced Exercise: Child-to-Parent Communication

    Create:

    text
    StudentCard

    with:

    text
    name
    onEnroll

    Parent:

    jsx
    function App() {
    function handleEnroll(name) {
    console.log(`${name} enrolled`);
    }
    return (
    <StudentCard
    name="Rahul"
    onEnroll={handleEnroll}
    />
    );
    }

    Child:

    jsx
    function StudentCard({
    name,
    onEnroll
    }) {
    return (
    <article>
    <h2>{name}</h2>
    <button
    onClick={() => onEnroll(name)}
    >
    Enroll
    </button>
    </article>
    );
    }

    The flow is:

    text
    App
    │
    │ name + onEnroll
    ▼
    StudentCard
    │
    │ click
    ▼
    onEnroll(name)
    │
    ▼
    App

    This pattern is fundamental to React.

    Interview questions & answers

    Interview preparation

    6 questions grouped by difficulty — expand any card for a model answer and follow-up probe.

    Beginner

    2
    1. 1What Are Props?
      Beginner

      Model answer

      Props, short for properties, are read-only inputs passed from a parent component to a child component.

      They allow components to receive data, configuration, JSX, and functions, making components reusable and composable.

    2. 2Are Props Mutable?
      Beginner

      Model answer

      Props should be treated as immutable by the receiving component.

      A child should not modify its props.

      If data needs to change, the appropriate state owner should update the data and pass the new value through props.

    Intermediate

    3
    1. 3How Does Data Flow in React?
      Intermediate

      Model answer

      React primarily follows one-way data flow.

      Data generally flows from parent components to children through props.

      When a child needs to trigger a change in parent-owned data, the parent can pass a callback function to the child.

    2. 4Can You Pass Functions Through Props?
      Intermediate

      Model answer

      Yes.

      A parent can pass a function to a child as a prop, and the child can invoke it in response to an interaction.

      This is a standard pattern for child-to-parent communication.

    3. 5What Is children?
      Intermediate

      Model answer

      children is a special prop containing the JSX or content nested between a component's opening and closing tags.

      It enables reusable wrapper and layout components.

    Advanced

    1
    1. 6Props vs State?
      Advanced

      Model answer

      Props are inputs supplied to a component, typically from its parent, and should be treated as read-only by the receiving component.

      State is data managed by a component or another state owner and can change over time.

      Changes to state or props can cause React to render updated UI.

    The Most Important Mental Model

    Think about every React component like a function:

    text
    Props
    │
    ▼
    ┌─────────────────┐
    │ Component │
    │ │
    │ Logic │
    └────────┬────────┘
    │
    ▼
    JSX
    │
    ▼
    UI

    For example:

    jsx
    function CourseCard({
    title,
    price
    }) {
    return (
    <article>
    <h2>{title}</h2>
    <p>₹{price}</p>
    </article>
    );
    }

    Then:

    jsx
    <CourseCard
    title="React"
    price={4999}
    />

    Think:

    text
    title = "React"
    price = 4999
    ↓
    CourseCard
    ↓
    JSX
    ↓
    UI

    Final Cheat Sheet

    Pass a string

    jsx
    <Greeting name="Rahul" />

    Pass a number

    jsx
    <Course price={4999} />

    Pass a boolean

    jsx
    <User isAdmin />

    Pass an array

    jsx
    <List items={items} />

    Pass an object

    jsx
    <User user={user} />

    Pass a function

    jsx
    <Button onClick={handleClick} />

    Receive props

    jsx
    function User(props) {
    return <h1>{props.name}</h1>;
    }

    Destructure props

    jsx
    function User({ name }) {
    return <h1>{name}</h1>;
    }

    Default value

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

    Children

    jsx
    function Card({ children }) {
    return <div>{children}</div>;
    }

    Don't mutate props

    jsx
    // ❌
    props.name = "John";

    The central idea of Props is:

    Props allow a parent component to provide data and behavior to a child component, making components reusable, configurable, and composable.

    The fundamental React flow is:

    text
    PARENT
    │
    │ Props
    ▼
    CHILD
    │
    │ renders
    ▼
    UI

    And for interactions:

    text
    PARENT
    │
    data + callback
    ▼
    CHILD
    │
    user interacts
    │
    ▼
    callback()
    │
    ▼
    PARENT

    If you understand props + JSX + functional components, you now have the core building blocks needed to start understanding state, events, and component communication in modern React.

    Ready to mark this lesson complete?Track your journey across the entire course.