Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Components and JSX  ›  Lesson

JSX — Markup Inside JavaScript

JSX 14 minJSX is HTML-like syntax inside JavaScript where curly braces hold any expression, attributes use camelCase names, and a component returns one root element.

JSX — Markup Inside JavaScript

JSX looks like HTML, so it is tempting to paste HTML straight in. Most of it works, and the parts that do not work fail in small, annoying ways. Learn the handful of differences once and you will stop tripping over them.

The rule

Braces open JavaScript; everything else is strict, camelCase HTML.

Braces let you drop any JavaScript expression into markup: a variable, a calculation, a function call.

const book = { title: 'The Hobbit', pages: 310, cover: '/hobbit.jpg' };

function BookCard() {
  return (
    <article className="book">
      <h2>{book.title}</h2>
      <p>{book.pages} pages, about {Math.round(book.pages / 30)} days</p>
      <img src={book.cover} alt={book.title} />
    </article>
  );
}

Only expressions fit in braces. An if statement or a for loop does not; you will meet the expression forms (? :, &&, map) in the Rendering section.

Strict means:

  • One root element per return. Wrap siblings in a parent or an empty fragment, <>...</>, which adds nothing to the page.
  • Every tag is closed: <img />, <br />, <input />.

camelCase HTML means attributes use JavaScript property names:

  • class → className, for → htmlFor
  • onclick → onClick, tabindex → tabIndex
  • style takes an object: style={{ fontSize: 18 }}. The outer braces open JavaScript; the inner braces are the object. Numbers mean pixels for most size properties.

Two exceptions keep their dashes: aria-* and data-* attributes, such as aria-label.

Comments inside markup go in braces too: {/* like this */}.

The shortcut

Before you trust a chunk of JSX, run the three-question scan: One root? All closed? Braces and camelCase where needed?

Scanning a pasted snippetStep 1 of 3
  1. One root?

    <h2>Title</h2><p>By</p> has two roots. Wrap them: <><h2>Title</h2><p>By</p></>.

A related trap: quotes make a string. alt="book.title" shows the words book.title; alt={book.title} shows the real title.

Behind the scenes, a build step turns each tag into a plain JavaScript function call. That is why JSX follows JavaScript's rules, not HTML's.

Drills

Answer fast — trust the rule.

quick drill

Which line correctly shows the value of the variable title?

quick drill

Which attribute gives an element a CSS class in JSX?

quick drill

Which style value is valid JSX?

quick drill

A component returns <h2>Hi</h2><p>There</p>. What is the smallest fix?

quick drill

Which of these can go inside { } in JSX?

Remember

  • Braces open JavaScript; they hold expressions, not statements.
  • Scan: one root? all closed? braces and camelCase where needed?
  • Trap: quotes make strings, and HTML's class, for and string style do not carry over.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainFix the HTML habits

Someone pastes this HTML into a component: <label for="q" class="big">Search</label><input id="q" style="color: red">. Explain every change needed to make it valid JSX, and why.