props IN → elements OUT (a component is a function)
props
object — and uses the returned element tree to build the DOM. So the
whole model is: props IN →
function runs →
elements OUT. Composition is just one
component rendering others; the children prop is the slot a
parent leaves for whatever you nest inside it.
| you want to… | pattern | here in the demo |
|---|---|---|
| pass data into a component | <Card title=… body=…/> → read via function Card({ title, body }) |
each Card gets a different title/body |
| give a prop a default | function Card({ tags = [] }) |
tags defaults to an empty array |
| render many of the same | array.map() → one element per item, each with a stable key |
cards.map() → 3 <Card/>; tags map to <Tag/> |
| slot arbitrary content into a wrapper | nested JSX arrives as the children prop |
<Wrapper><Card/>…</Wrapper> → Wrapper({ children }) |
Component names start with a capital letter — that is how JSX
tells a component (<Card/>) from an HTML tag
(<div/>). Props are read-only: never mutate
them; if data must change, the parent passes new props (or you reach for
state — see react_via_cdn for the loader, and the upcoming state/hooks bundle).
1 · the JSX you write (edit me)
2 · Babel compiles JSX into an element tree
Babel turns <Card title="x"/> into
React.createElement(Card, { title: "x" }) — a plain-object
React element. React walks that element tree and, because
Card is itself a component, calls it with the props
object to get its subtree. That recursion — parent element →
call child function with props → child element — is composition.
// (hit “compile & render” to see Babel’s output here)
3 · createRoot renders the composed tree into the DOM
createRoot(#root).render(<App/>) mounts React 19. Here
<App/> composes a <Wrapper> whose
children slot is filled by mapping an array into three
<Card/>s — each <Card/> then maps
its tags array into <Tag/>s. Edit a
title above and re-render to watch props flow down into the DOM.
cards rendered: 0 · 3rd title present? — · root text: —