Skip to content

Join the Seedly owners community →

React

Components & JSX

Learn how to build React components and write JSX, the special syntax that combines HTML with JavaScript

Written by 14 min read1 activity
Sprout, your presenter

Sprout presents

Components are reusable building blocks, and JSX lets you write HTML-like markup inside JavaScript. The curly braces section is particularly delightful.Components are reusable building blocks, and JSX lets you write HTML-like markup inside JavaScript. The curly braces section is particularly delightful.

Sprout cuts star cookies from dough, next to a row of identical stars iced in different colours
A component is a cookie cutter you can reuse again and again

Think of a React component like a cookie cutter. Design the shape once and you can stamp out as many cookies as you want. Every cookie (that's a component instance) has the same shape, but each one can get different decorations (that's the data). Components are the building blocks of every single React app.

What is a Component?#

A React component is just a JavaScript function that returns JSX (which looks like HTML). Seriously, that's it! Here's the simplest component you can write.

function Greeting() {
  return <h1>Hello, World!</h1>;
}

Three things make that a valid React component.

  1. It's a function - and its name starts with a capital letter (this one is REQUIRED!)
  2. It returns JSX - that's the HTML-looking stuff inside the return
  3. It's reusable - you can drop <Greeting /> anywhere in your app

Understanding JSX#

JSX stands for JavaScript XML, and it lets you write HTML-looking code right inside your JavaScript. Under the hood it gets compiled down to regular JavaScript. The HTML-looking version is just WAY easier for humans to read and write.

// This JSX:
const element = <h1 className="title">Hello!</h1>;
 
// Gets compiled to roughly this JavaScript:
import { jsx as _jsx } from 'react/jsx-runtime';
const element = _jsx('h1', { className: 'title', children: 'Hello!' });

You'll never write that _jsx version yourself. Your build tool adds it for you, import line and all (which is also why you don't need import React from 'react' at the top of every file anymore). Older tutorials show React.createElement here instead, since that's what JSX used to compile to. Either way the takeaway is the same... JSX is really just a friendlier way to create elements.

JSX Rules#

JSX has a few rules that are a lil different from HTML. Here they are.

Step 1. Use className Instead of class#

The word class is already reserved in JavaScript, so JSX uses className for CSS classes instead.

// HTML:  <div class="container">
// JSX:
<div className="container">Content</div>

Step 2. Close All Tags#

Every tag has to be closed in JSX. That includes self-closing tags like <img /> and <br />, which plain HTML lets you get away with leaving open.

// HTML:  <img src="photo.jpg">     (no closing needed)
// JSX:
<img src="photo.jpg" />    // Must self-close!

Step 3. Return a Single Root Element#

A component can only return one top-level element. If you've got more than one, wrap them in a <div> or a Fragment (<>...</>).

// This breaks (two root elements):
function Bad() {
  return (
    <h1>Title</h1>
    <p>Text</p>
  );
}
 
// This works (wrapped in a Fragment):
function Good() {
  return (
    <>
      <h1>Title</h1>
      <p>Text</p>
    </>
  );
}

JavaScript in JSX: Curly Braces#

Here's where JSX gets fun. You can drop JavaScript expressions right into it using curly braces { }. Think of curly braces as an escape hatch out of HTML-land and back into JavaScript-land.

function UserCard() {
  const name = "Sarah";
  const age = 25;
  const hobbies = ["coding", "reading", "hiking"];
 
  return (
    <div>
      <h2>{name}</h2>
      <p>Age: {age}</p>
      <p>Hobbies: {hobbies.join(", ")}</p>
      <p>Is adult: {age >= 18 ? "Yes" : "No"}</p>
    </div>
  );
}

Pretty much any JavaScript expression can go inside curly braces.

  • Variables like {name}
  • Math like {2 + 2}
  • Function calls like {name.toUpperCase()}
  • Ternary expressions like {isOnline ? "Online" : "Offline"}

Component Composition#

The real magic happens when you start putting components inside other components. That's called composition, and it's how you build big complicated UIs out of small simple pieces.

function Avatar({ imageUrl }) {
  return <img src={imageUrl} className="avatar" />;
}
 
function UserInfo({ name, imageUrl }) {
  return (
    <div className="user-info">
      <Avatar imageUrl={imageUrl} />
      <h3>{name}</h3>
    </div>
  );
}
 
function App() {
  return (
    <div>
      <UserInfo name="Alice" imageUrl="/alice.jpg" />
      <UserInfo name="Bob" imageUrl="/bob.jpg" />
    </div>
  );
}

See how App uses UserInfo, which in turn uses Avatar? Each component is small and focused on one job. So if you want to change how avatars look, you update the Avatar component ONE time, and every place that uses it updates automatically.

Fragments: The Invisible Wrapper#

Sprout opens wooden nesting dolls, a small doll inside a medium one inside a large one
Composition means building components out of other components

Sometimes you need to return several elements but you don't want an extra <div> showing up on the page. That's exactly what Fragments are for.

function TableRow() {
  return (
    <>
      <td>Name</td>
      <td>Age</td>
      <td>City</td>
    </>
  );
}

Those empty tags <>...</> group elements together without adding any HTML to the page at all. They come in clutch inside tables, lists and flex containers, where one extra <div> would wreck your layout.

A Complete Example#

Alright, here's a more realistic component that pulls everything together.

function ProductCard({ name, price, inStock, imageUrl }) {
  const formattedPrice = `$${price.toFixed(2)}`;
 
  return (
    <div className="product-card">
      <img src={imageUrl} alt={name} />
      <h3>{name}</h3>
      <p className="price">{formattedPrice}</p>
      <p className={inStock ? "in-stock" : "out-of-stock"}>
        {inStock ? "In Stock" : "Out of Stock"}
      </p>
      <button disabled={!inStock}>
        {inStock ? "Add to Cart" : "Unavailable"}
      </button>
    </div>
  );
}

That one component can display any product and adjust how it looks based on whether it's in stock. You could use it 100 times on a page with 100 different products (and you'd only ever fix bugs in one spot... wholesome right?)

TL;DR#

  • A React component is a function that returns JSX (and its name has to start with a capital letter)
  • JSX looks like HTML but lives inside JavaScript, uses className instead of class, and needs every tag closed
  • Use curly braces { } to drop JavaScript expressions into JSX
  • Component composition lets you build big UIs out of small, reusable pieces
  • Fragments (<>...</>) group elements without adding extra DOM nodes

What's Next?#

Right now your components are static. They show the same thing every time. In the next lesson you'll learn how to give them a memory with State, so they can actually react when somebody clicks something...

This lesson ends with a short activity.