Components & JSX
UI as a function of data — the one idea React is built on.
40 minDifficulty 2/5reactAI-writtenWritten by a model on 16 August 2026 and not yet read by a person. Checked automatically: schema, the pedagogical rules the hand-written material is held to, and every diagram parsed for real.
Before this
Why this exists
Before component frameworks, updating a piece of UI meant manually finding the right DOM node and mutating it — and remembering every place that data appeared, so all of them stayed in sync. React replaces that with one idea: describe what the UI should look like given the current data, as a function, and let React figure out what actually needs to change on screen.
The mental model
A component is a function that takes data (props) and returns a description of UI (JSX). Call it with the same props twice, get the same description twice — it's meant to behave like a pure function of its inputs, at least for what it renders. React calls this function whenever the data might have changed, and compares the new description to the old one to update only what's different.
How it works
JSX is JavaScript, compiled
`<div className="card">{title}</div>` isn't HTML — it's syntax that compiles to `React.createElement('div', { className: 'card' }, title)`, a plain JavaScript function call returning a plain object. This is why you can embed any JavaScript expression inside `{}` in JSX: it's just an argument to a function call, evaluated like any other expression.
Props flow one direction: parent to child
A component receives data via props and cannot modify them — props are read-only from the child's perspective. If a child needs to change something the parent owns, the parent passes down a function (often called a callback) as a prop, and the child calls that function; the actual state change happens in the parent, one level up.
Composition beats configuration
Instead of a `<Card variant="withHeader" variant2="withFooter" showBorder>` prop explosion, React favours composing smaller components together: `<Card><CardHeader/><CardBody/><CardFooter/></Card>`. Each piece stays simple and focused, and new combinations don't require touching the base component's prop list at all.
Keys tell React which item is which across renders
Rendering a list without a stable `key` prop leaves React guessing which array item on the new render corresponds to which DOM element from the old render — it falls back to matching by position, which breaks badly when items are reordered, inserted, or removed. A stable, unique key (an id, never the array index for a reorderable list) lets React correctly track each item's identity across renders.
The mechanism
React calls a component function with its current props, receiving back a JSX tree describing the desired UI. React compares this new tree to the tree from the previous render (a process called reconciliation) and computes the minimal set of real DOM changes needed to make the screen match — rather than tearing down and rebuilding everything from scratch on every update.
flowchart LR P[Props in] --> C[Component function] C -->|returns| J[JSX description] J -->|React reconciles against previous| D[Actual DOM updates]
What people get wrong
- JSX is a templating language, similar to a string template.
- JSX compiles directly to nested JavaScript function calls returning plain objects — it has the full power (and constraints) of JavaScript expressions inside it, not a separate limited templating syntax. Thinking of it as a template leads people to try things templating languages allow but plain JavaScript expressions inside braces don't, like an if/else statement directly inline instead of a ternary or a variable computed beforehand.
- You can pass a prop from a child back up to modify the parent's state directly.
- Props only flow downward; a child can only affect a parent's state by calling a function the parent explicitly passed down for that purpose — there's no built-in mechanism for a child to reach up and mutate a parent's variables directly. Expecting bidirectional data flow leads to attempts at patterns React doesn't support, and obscures where state actually lives and changes in the component tree.
- Using the array index as a list's `key` is always fine.
- Index-as-key works only when the list never reorders, inserts, or removes items in the middle — otherwise React misattributes state and DOM elements to the wrong logical item after a change, causing subtle bugs like an input field's typed text jumping to the wrong row. Index-as-key is the easiest thing to reach for and often appears to work in a quick test, hiding a bug that only shows up once the list actually gets reordered in production.
When not to use it
- A component's output depends on data that changes very frequently, like mouse position on every pixel of movement.
- Consider whether that value needs to trigger a React re-render at all, or can be handled with a direct, imperative DOM update or a ref — re-rendering an entire component tree on every mouse-move event can be unnecessarily expensive.
- You need genuinely bidirectional communication between sibling components.
- Lift the shared state up to their common parent, which then passes data down to both and a callback down to whichever one needs to trigger a change — see `react-state`.
Terms
- Props
- — The read-only data a component receives from its parent, analogous to function arguments.
- JSX
- — Syntax that compiles to JavaScript function calls (React.createElement or equivalent) describing a tree of UI elements.
- Reconciliation
- — React's process of comparing a new render's output tree to the previous one to compute the minimal actual DOM changes needed.
- Key
- — A prop given to list items that provides a stable identity across renders, letting React correctly track which item is which even as the list changes.
In an interview
Why can using array index as a React key cause bugs when a list is reorderable?
- React uses key to match old and new elements by identity, not position
- index-as-key means position IS the identity, so reordering makes React think the wrong items changed
- this can misattribute component state (like input values) to the wrong logical item after a reorder
Can you recall it?
What does it mean that a React component is 'a function of its props', and why does that matter for how JSX gets turned into actual UI updates?