React · Topic 1 of 8

JSX and components

Card 1 of 14

What you will learn

JSX is a syntax extension that lets you write markup inside JavaScript, and function components are the functions that return it. Together they are the basic building blocks of every React UI.

What JSX is

JSX looks like HTML but is JavaScript. An expression like <div id="a">Hi</div> evaluates to a plain object, a React element, describing what to render. Put any JavaScript expression in curly braces to display it.

A few attribute names differ from HTML: className instead of class, and style takes an object, so inline styles use double braces. Tags with no children must be self-closed, like <img />. Comments between children are written {/* like this */}.

Example

What JSX is

const title = 'Hello';
const el = (
  <h1 className="big" style={{ color: 'red' }}>
    {title}
    {/* a JSX comment */}
  </h1>
);

Components are functions

A function component is a JavaScript function that takes props and returns JSX. Its name must start with a capital letter. Lowercase tags such as <widget /> are treated as built-in DOM elements and the function is never called.

Define components at the top level of a file, not inside other components. A component defined inside another is a new type on every render, so React remounts it and its state resets.

Example

Components are functions

function ProfileCard({ name }) {
  return <p>Hi, {name}</p>;
}

// To choose at runtime, store it in a capitalised variable
const Panel = isAdmin ? AdminPanel : UserPanel;
// <Panel />

One root and Fragments

A component returns a single value, so sibling elements need a wrapper. Use a Fragment, <>...</>, to group them without adding a DOM node. In a map, where you need a key, write <Fragment key={id}> using the imported name.

Beware of return followed by a line break: automatic semicolon insertion ends the statement and returns undefined. Open parentheses on the return line.

Example

One root and Fragments

function Info() {
  return (
    <>
      <h1>Title</h1>
      <p>Details</p>
    </>
  );
}

Props and children

Attributes on a component tag become its props. A bare attribute like <Toggle disabled /> gives the value true. Props are read-only: never assign to them. With spread, later attributes win, so <Profile name="X" {...props} /> uses the name in props. Default values in destructuring apply only to undefined, not to null.

Anything between opening and closing tags arrives as props.children.

Example

Props and children

function Card({ children, size = 40 }) {
  return <div style={{ width: size }}>{children}</div>;
}
// <Card><p>Hi</p></Card>

Rendering values, lists and events

Strings and numbers render; plain objects throw an error. With {count && <p>..</p>}, a count of 0 renders the number 0, so use count > 0 instead. In JSX text, lines are trimmed and joined, and a newline between text and an expression leaves no space.

Render lists with map and give each item a stable key. Pass event handlers as functions: onClick={handleClick}, not handleClick(), which would run during render. Keep render pure, with no changes to outside variables. Changing a component's key resets its state, and the same component type in the same position keeps its state.

Example

Rendering values, lists and events

<ul>
  {items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
<button onClick={handleClick}>Save</button>

Key points

  • JSX compiles to plain objects (React elements) describing the UI.
  • Components are functions with capitalised names that return JSX.
  • Use className, style objects, self-closing tags and {/* */} comments.
  • Wrap siblings in a Fragment; props are read-only and children holds nested content.
  • Lists need stable keys; pass handlers, do not call them.
  • Keep rendering pure and define components at the top level.

Common mistakes

  • Using {count && <X />} when count can be 0, which displays 0.
  • Writing onClick={handleClick()} so the handler runs during render.
  • Declaring a component inside another component, which resets its state each render.
  • Starting a component name with a lowercase letter.
  • Putting a line break after return so it returns undefined.

Lesson complete

Ready to check what you learned?

Swipe left or right, or use the buttons.