LearnFrenzy
Sign in Take a free test

Getting Started with React · Lesson 3 of 31

JSX in React

5 min read Updated Nov 8, 2026 Saurabh Samir

JSX is a syntax extension that lets you write HTML-like markup inside JavaScript. It isn't HTML and it isn't a string: the build tool turns each tag into a function call that creates a plain JavaScript object. Once you know its handful of rules, JSX makes components easy to read.

In this lesson

  • Embedding JavaScript with { }
  • Attributes: className, htmlFor, camelCase events, inline styles
  • One root element and fragments
  • What JSX compiles to, and why it's safe from XSS

Expressions in curly braces

Anything inside { } is a JavaScript expression: a variable, a calculation, a function call, a ternary.

const user = { firstName: "Asha", lastName: "Verma", points: 1240 };
const formatName = (u) => `${u.firstName} ${u.lastName}`;

export default function App() {
  const level = user.points >= 1000 ? "Gold" : "Silver";
  return (
    <div>
      <h1>Welcome back, {formatName(user)}</h1>
      <p>Points: {user.points.toLocaleString("en-IN")}</p>
      <p>Level: {level}</p>
      <p>Next reward in {2000 - user.points} points</p>
      <p>Today is a {["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][new Date(2026, 10, 9).getDay()]}</p>
    </div>
  );
}

Result

Welcome back, Asha Verma
Points: 1,240
Level: Gold
Next reward in 760 points
Today is a Mon

Expressions only, not statements

You can't put if, for or const inside { }. Compute values before the return, or use a ternary, && or map – all expressions. The next chapter covers conditional rendering and lists.

Attributes

const course = { title: "React.js", cover: "/img/react.png", url: "/learning/react" };

export default function App() {
  const isNew = true;
  return (
    <article className={isNew ? "card card--new" : "card"}>
      <img src={course.cover} alt={`${course.title} course cover`} width={320} />
      <a href={course.url}>{course.title}</a>
      <label htmlFor="email">Get updates</label>
      <input id="email" type="email" placeholder="you@example.com" disabled={false} />
      <p style={{ color: "#087ea4", fontWeight: 600, marginTop: 8 }}>Free course</p>
    </article>
  );
}

Result

(image: React.js course cover) React.js Get updates [you@example.com…]
Free course
HTMLJSXWhy
classclassNameclass is a JavaScript keyword
forhtmlForfor is a keyword too
onclickonClickattributes are camelCase
style="color: red"style={{ color: "red" }}style takes an object; numbers mean px
<br>, <img><br />, <img />every tag must be closed

The double braces in style={{ … }} aren't special syntax: the outer pair means "JavaScript here", the inner pair is an object literal. aria-* and data-* attributes keep their dashes.

One root element, or a fragment

A component returns one value, so JSX must have a single parent. Returning two siblings is a compile error:

export default function Profile() {
  return (
    <h2>Asha Verma</h2>
    <p>Frontend developer</p>
  );
}

Compile errors

main.tsx(3,5): error TS2657: JSX expressions must have one parent element.

Wrap them in a fragment, <>…</>, which groups elements without adding an extra div to the page:

function Profile() {
  return (
    <>
      <h2>Asha Verma</h2>
      <p>Frontend developer</p>
    </>
  );
}

export default function App() {
  return (
    <section>
      {/* a comment inside JSX uses braces */}
      <Profile />
    </section>
  );
}

Result

Asha Verma
Frontend developer

What JSX compiles to

// You write:
const el = <a href="/learning/react" className="link">React</a>;

// The build tool produces (React 17+ "automatic runtime"):
import { jsx as _jsx } from "react/jsx-runtime";
const el = _jsx("a", { href: "/learning/react", className: "link", children: "React" });

// …which returns a plain object, roughly:
// { type: "a", props: { href: "/learning/react", className: "link", children: "React" } }

That object is a React element – a description of what to show, not a DOM node. Lowercase tags (a, div) become HTML elements; capitalised ones (Profile) are your components. That's why component names must start with a capital letter.

JSX escapes text automatically

export default function App() {
  const comment = '<img src=x onerror="alert(1)"> Nice course!';   // e.g. user input
  return <p>{comment}</p>;
}

Result

<img src=x onerror="alert(1)"> Nice course!

Safe by default

React inserts strings as text, never as HTML, so the injected tag above is shown harmlessly instead of running. The escape hatch is dangerouslySetInnerHTML={{ __html: html }} – only use it with HTML you have sanitised (for example with DOMPurify).

Practice

Try it yourself

  1. Build a PriceTag that shows a product name, the price formatted as rupees, and "In stock" in green or "Sold out" in grey.

    Show solution
    const product = { name: "Mechanical Keyboard", price: 3499, stock: 0 };
    
    export default function App() {
      const inStock = product.stock > 0;
      return (
        <div className="price-tag">
          <h3>{product.name}</h3>
          <p>{product.price.toLocaleString("en-IN", { style: "currency", currency: "INR" })}</p>
          <p style={{ color: inStock ? "green" : "grey" }}>{inStock ? "In stock" : "Sold out"}</p>
        </div>
      );
    }

    Result

    Mechanical Keyboard
    ₹3,499.00
    Sold out

Quick check

How do you set a CSS class in JSX?

With className.

Why must component names be capitalised?

Lowercase tags are treated as HTML elements; capitalised ones as components.

How do you return two sibling elements without a wrapper div?

Wrap them in a fragment: <>…</>.

Summary

  • JSX is JavaScript: { } holds expressions, attributes are camelCase, style takes an object.
  • Return one root element or a fragment; close every tag.
  • JSX compiles to jsx() calls that create React elements, and text is escaped automatically.

Finished this lesson?

Mark it complete to track your progress, then carry on with the next lesson.

Next lesson

Popular