React Foundations·Components, state and data

Props and composition

Compose components by passing typed props and children instead of locking in behaviour.

Intermediate 11 min read Lesson 2 of 300 Challenge included
What you will be able to do
  • Type a props object with an interface or inline type.
  • Use children to let callers compose markup inside a component.
  • Forward props with rest when wrapping a native element.
  • Prefer composition over long lists of boolean configuration props.

In plain English

A prop is a named input a component receives from its parent. In TypeScript you describe the shape of those props with a type so mistakes are caught before the app runs. The children prop is special: it lets a parent place any markup between the opening and closing tags of a component, which is called composition. Prefer composition over passing many configuration flags, and spread props only when you truly want to forward everything.

Step by step

  1. 1Define a type that names every prop and its value type.
  2. 2Destructure props in the parameter list with sensible defaults.
  3. 3Render children exactly where the caller should control the content.
  4. 4Spread rest only when forwarding to a single native element.
Badge.tsxTSX
import type { ComponentProps, ReactNode } from 'react'

type BadgeProps = {
  tone?: 'neutral' | 'success' | 'danger'
  children: ReactNode
}

function Badge({ tone = 'neutral', children }: BadgeProps) {
  return <span className={'badge badge-' + tone}>{children}</span>
}

type ButtonProps = ComponentProps<'button'>

function Button(props: ButtonProps) {
  return <button {...props} />
}

Common mistakes

  • Spreading props everywhere hides which values a component actually reads and makes refactoring painful.
  • Using a boolean flag for every minor variation turns a component into a configuration mess that is hard to test.
  • Leaving children untyped lets a caller pass anything, and the component fails at runtime.
  • Passing one giant object as a single prop is harder to read than a few named props.
Your turn

Build a Card wrapper

Easy

Create a Card component that accepts a title prop and children, and a Panel component that forwards all its props to a native div.

TSX · starter
import type { ReactNode } from 'react'

function Card({ title, children }: { title: string; children: ReactNode }) {
  return (
    <section>
      <h2>{title}</h2>
      {children}
    </section>
  )
}
Check your understanding before moving on.
Knowledge checkQuestion 1

Why is the children prop useful for composition?

Select an answer to continue
Study tools

Make it yours.

Keep a private note for this lesson, then turn the key ideas into flashcards you can revisit.

Sign in to save notes and flashcards.Both are private to your account and stay with your progress.
Sign in
Finished reading?

Lock in what you just learned.

Mark this lesson complete to save your place and move one step closer to the certificate.

Next: State with useReducer
Lesson 2 of 300 · 0% of course