How to Send Data from Parent to Child in React

Beginner8 min interview
Skills tested:
Passing primitive values, objects, arrays, and functions as propsTyping props with TypeScript interfacesUsing the spread operator to forward props to a child componentUnderstanding that props are read-only and children cannot modify themUsing the children prop to pass JSX content into a component

Advertisement

🧩 Scenario

Passing data from parent to child is the fundamental mechanism of React composition. Understanding what can be passed as props (literally any JavaScript value) and what the child can do with them (read only, never modify) establishes the mental model for all of React data flow.

Architecture Walkthrough

What Can Be Passed as a Prop

Any JavaScript value can be a prop: strings, numbers, booleans, objects, arrays, functions, React elements, and even other components. Props are passed as JSX attributes in the parent and received as a single props object in the child. Boolean props can use the shorthand <Button disabled /> which is equivalent to <Button disabled={true} />.

Props are the data channel for parent-to-child communication. When the parent re-renders with a new value for a prop, the child receives the new value and React reconciles the child's output accordingly.

Props Are Read-Only

Props are immutable from the child's perspective. A component that receives props must not modify them. This constraint is central to React's predictable data flow: the parent owns the data and controls when it changes. If the child needs to change a value, it calls a callback function received as a prop, and the parent decides how to update its own state.

Mutating a prop object property (props.user.name = 'new') does mutate the underlying JavaScript object (since objects are passed by reference), but it does not trigger a React re-render. It also violates the React model and causes bugs that are difficult to trace.

The children Prop

children is a special prop that contains the JSX content placed between the opening and closing tags of a component. It enables wrapper components, layout components, and slot patterns. Typing children in TypeScript uses React.ReactNode, which accepts elements, strings, numbers, null, and arrays.


Key Code Explained

// Typing props in TypeScript
interface UserCardProps {
  name: string;                    // required string
  age: number;                     // required number
  isVerified: boolean;             // required boolean
  tags: string[];                  // required array
  onFollow: () => void;            // required callback
  avatar?: string;                 // optional string
}

function UserCard({ name, age, isVerified, tags, onFollow, avatar }: UserCardProps) {
  return (
    <div className="user-card">
      {avatar && <img src={avatar} alt={name} className="avatar" />}
      <h3>{name}</h3>
      <p>Age: {age}</p>
      {isVerified && <span className="badge">Verified</span>}
      <ul>
        {tags.map((tag) => (
          <li key={tag}>{tag}</li>
        ))}
      </ul>
      <button onClick={onFollow}>Follow</button>
    </div>
  );
}

// Parent passes values via JSX attributes
function App() {
  return (
    <UserCard
      name="Ghazi Khan"
      age={28}
      isVerified         // shorthand for isVerified={true}
      tags={['React', 'TypeScript', 'Node.js']}
      onFollow={() => console.log('Followed!')}
      avatar="/avatars/ghazi.png"
    />
  );
}


// Passing components and elements as props
interface CardProps {
  title: string;
  icon: React.ReactNode; // any renderable: element, string, number, null
  children: React.ReactNode; // content between open and close tags
}

function Card({ title, icon, children }: CardProps) {
  return (
    <div className="card">
      <header className="card-header">
        {icon}
        <h2>{title}</h2>
      </header>
      <div className="card-body">{children}</div>
    </div>
  );
}

// Usage: children is the JSX between the tags
function Dashboard() {
  return (
    <Card title="Analytics" icon={<ChartIcon />}>
      <p>Traffic: 12,400 visits today</p>
      <p>Conversion: 3.2%</p>
    </Card>
  );
}


// Prop spreading: forward known props to a DOM element
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  label: string;
  error?: string;
}

function LabeledInput({ label, error, ...rest }: InputProps) {
  // rest contains all HTML input attributes (placeholder, type, value, onChange, etc.)
  return (
    <div className="input-wrapper">
      <label>{label}</label>
      <input {...rest} className={error ? 'input-error' : 'input'} />
      {error && <span className="error-message">{error}</span>}
    </div>
  );
}

// Usage: any valid input attribute can be passed
<LabeledInput
  label="Email"
  type="email"
  value={email}
  onChange={(e) => setEmail(e.target.value)}
  placeholder="name@example.com"
  error={emailError}
/>

Extending React.InputHTMLAttributes<HTMLInputElement> for the InputProps interface is the idiomatic way to build wrapper components around HTML elements in TypeScript. It gives the parent access to all native input attributes without needing to enumerate them manually, and future HTML attributes are automatically included.


Tradeoffs

Prop typeNew reference each renderAffects React.memoNotes
Primitive (string, number, boolean)NoNoSafe to pass inline
Object / array literal in JSXYesYes (breaks memo)Extract as constant or use useMemo
Inline arrow functionYesYes (breaks memo)Use useCallback for memoized children
Stable reference (const, useMemo, useCallback)NoNoCorrect for memoized children

What Interviewers Actually Check

  • Whether you know props are read-only and what to do when the child needs to signal a change
  • Whether you can type props correctly in TypeScript
  • Whether you know about the children prop and how to type it
  • Whether you know that inline objects and functions create new references on every render
  • Whether you can use prop spreading to build wrapper components

Follow-Up Questions

  1. What is the difference between React.ReactNode and React.ReactElement for typing the children prop?
  2. How does React.cloneElement allow a parent to inject additional props into a children element?
  3. How would you build a Tooltip component that wraps any child element and shows a tooltip on hover without using a render prop?
  4. What is the render prop pattern and how does it differ from using children as JSX?
  5. How do you pass a generic typed component as a prop with a TypeScript generic constraint?

Common Candidate Mistakes

  • Trying to modify props.user.name directly inside the child and not knowing why the parent's data is affected but the component does not re-render
  • Not knowing about the children prop and re-implementing slot patterns by passing JSX as a custom prop
  • Passing { onClick: () => doSomething() } as a prop inside JSX and not knowing it creates a new reference every render
  • Using ...props spread without knowing which props are being forwarded, accidentally forwarding unknown attributes to DOM elements (which React warns about)
  • Confusing props (received, read-only) with state (owned, mutable)

Interview Readiness Checklist

Before you leave this question, make sure you can answer:

  • Can you pass strings, numbers, booleans, objects, arrays, and functions as props?
  • Can you type a props interface in TypeScript including optional props?
  • Can you use the children prop to build wrapper or layout components?
  • Can you explain why props are read-only and what the child should do when it needs to signal a value change?
  • Can you use prop spreading to forward HTML attributes to a DOM element wrapper?

Summary

Props are the mechanism for parent-to-child data flow in React. Any JavaScript value can be a prop: primitives, objects, arrays, functions, React elements, or other components. Props are passed as JSX attributes by the parent and received as a destructured object in the child.

Props are read-only inside the receiving component. The parent owns the data and controls when it changes. If the child needs to signal a change, it calls a callback function received as a prop. Mutating prop properties directly (even if JavaScript allows it on objects) violates React's data flow model and produces bugs without triggering re-renders.

The children prop is a special prop that receives JSX content placed between a component's opening and closing tags, enabling wrapper components, layouts, and slot-based composition. In TypeScript, type children as React.ReactNode to accept any renderable content. Inline objects, arrays, and functions in JSX create new references on every render, which breaks memoization for children wrapped in React.memo.

Related Videos
Watch these videos to learn more about this topic
Frequently Asked Questions

Can a child modify the props it receives?

No. Props are read-only inside the component that receives them. Only the parent that passed them can change the value. If the child needs to signal a change, it calls a callback function passed as a prop.

Advertisement


Stay Updated

Get the latest frontend challenges, interview questions and tutorials delivered to your inbox.

Advertisement