← React: components, state and interface decisions
01 / 10 · 60 MIN

Components, props and pure rendering

Build web components that receive data and describe an interface without changing inputs. Interpret JSX, composition and the difference between render and commit.

Read a component’s contract

A function component receives inputs and returns a description of the interface. In JSX, capitalized OrderSummary references the example’s function; section and p identify native elements. Neither the filename nor displayed text replaces this distinction.

Before analyzing a page, write down the contract: which props arrive, which are optional and what content is returned. Here orders is required and each object contains an identifier, customer and numeric total. This example does not imply that every API response has that shape.

Boundary data validation belongs to the application contract. Functions, arrays and objects are JavaScript prerequisites; this lesson focuses on React’s use of those inputs.

JSX and grouping without an extra container

JSX is syntax for describing output; it is not an HTML string to insert automatically. Close tags and use the intended properties, such as className. When an expression returns adjacent elements, a Fragment written as <>...</> groups them without adding a container element to the DOM.

A div without attributes is still an element; CSS changing its presentation does not remove it from the DOM either. Choose a section when you actually want a section and suitable semantic structure, as in the example, rather than adding a container merely to satisfy syntax.

A Fragment solves grouping but does not itself provide an accessible heading or define relationships between controls.

Props, defaults and changing data

Props are a snapshot of inputs for this render. Read-only means the child should not change received values; it does not prevent the parent from supplying other values on the next render. If the parent replaces the order list, the summary calculates the new list’s total.

The currency = EUR default applies when the prop is missing or undefined. It does not replace null, zero or an empty string. A default therefore is not a complete validation policy.

When investigating a blank currency, distinguish a missing prop, explicit null and an empty string first. Then decide whether the contract should reject that data, normalize it at the boundary or deliberately allow that presentation.

Composition through children

Panel receives a title and nested content. React supplies that content through the children prop; Panel chooses where to include it in JSX. If it returns only an empty section, the parent’s paragraphs do not appear in that output.

Composition allows the same frame to hold a summary, warning or other content without making Panel know every case’s details. Avoid looking up a child’s name in a global variable or treating a CSS class as an insertion mechanism. The contract is clearer when the frame owns its structure and the caller provides content.

A function callback prop also requires explicit wiring; the next lesson applies that idea to events.

Purity and object ownership

Rendering should not change objects that existed before the call or depend on changes to a global counter. The example calculates total and names from orders without modifying the array or orders. Creating a new local array and filling it during this call can be compatible with purity; changing the received array is a different operation.

To sort the presentation, a copy such as [...orders].sort(compare) protects the original array order when compare is pure. That copy is shallow: it does not permit writing to nested objects. During review, trace each reference and ask whether the object was created in this call or belongs to the parent, another component or a shared module.

Render, commit and observable effects

React can calculate an interface again before applying changes. Rendering determines the description; commit applies necessary changes to the DOM. A component-call record proves neither that every element was recreated nor that nothing changed.

Rendering should not trigger an irreversible external operation either. If the requirement is to submit an order after confirmation, attach submission to that interaction’s handler. Do not use render frequency as a submission counter.

Effects serve synchronization with external systems when needed; indiscriminately moving submission to an Effect does not establish a connection to user confirmation. Component identity and state-preservation boundaries are covered in a later lesson.

Contract-oriented review

In a dashboard with unstable order numbers, first check whether the identifier comes from persistent data or a render count. A global counter mixes business identity with presentation work that may repeat. In a card approving an order, next locate state ownership: if the parent controls the list, the child can communicate onApprove(order.id), and the parent can decide the change and supply new props.

It is insufficient for direct mutation to appear to work after an incidental render. Complete the review by recording inputs, intended output, objects that remain intact and the interaction responsible for effects. Assessment asks you to select decisions and interpret excerpts; it does not require running the example.

// Reading example: React web component; orders supplied by the parent.
// Each order has {id: string, customer: string, total: number}.
function Panel({title, children}) {
  return <section><h2>{title}</h2>{children}</section>;
}

export default function OrderSummary({orders, currency = 'EUR'}) {
  const total = orders.reduce((sum, order) => sum + order.total, 0);
  const names = orders.map(order => order.customer).join(', ');
  return (
    <Panel title="Orders awaiting review">
      <p>{orders.length} orders: {names}</p>
      <p>Total: {total} {currency}</p>
    </Panel>
  );
}
IN PRACTICE

With two orders totaling 12 and 18, OrderSummary derives 30 without writing to the objects. Omitting currency uses EUR; passing null does not activate the default. Panel displays the paragraphs because it includes children.

The example omits currency formatting and data validation to delimit the render contract.

Common pitfalls

Confusing read-only with permanently fixed values; expecting children to appear without rendering it; using a global counter to generate order numbers; assuming a new render recreates every DOM node.

Related topics: Events, state snapshots and update queues · State structure and component identity

Take this idea with you

A component describes output from current inputs. Props can change between renders, but the component does not change them. Explicit composition and pure calculation allow work to repeat without modifying external data.

Create account

Reference: Defining components · React 19.3.0; JSX