Skip to content

React · Components

React JSX — A Complete Guide with Examples

6 min read Updated 2026-06-23 Share:

Practice JSX and Rendering interview questions

What JSX really is

Every React developer writes JSX, but many treat it as magic. Interviewers know this and will ask questions designed to reveal whether you understand it as syntax sugar or as a black box.

JSX is a syntax extension to JavaScript that looks like HTML but compiles to plain JavaScript. A build tool — Babel, SWC, or the TypeScript compiler — transforms every JSX expression into a function call before the browser ever sees it:

// What you write
const button = <button className="primary">Save</button>

// What the compiler produces (React 17+ JSX transform)
import { jsx as _jsx } from 'react/jsx-runtime'
const button = _jsx('button', { className: 'primary', children: 'Save' })

The result is a plain JavaScript object called a React element — a lightweight description of what should appear on screen. React's renderer later turns it into actual DOM nodes. Nothing magic, just objects.

Why JSX requires a single root

Because JSX compiles to a single function call that returns one value. You can't return two values from one expression in JavaScript.

// ❌ Two adjacent top-level elements
return (
  <h1>Title</h1>
  <p>Body</p>
)

// ✅ Fragment — groups siblings without adding a DOM node
return (
  <>
    <h1>Title</h1>
    <p>Body</p>
  </>
)

The short syntax <>…</> is the most common form. Use <React.Fragment key={id}>…</React.Fragment> only when you need to attach a key prop (for example in a list).

Embedding JavaScript expressions

Anything that produces a value goes inside {}. Strings, numbers, function calls, ternaries, template literals — all valid. Statements (if, for, variable declarations) are not, because they don't produce values.

const name = 'Alice'
const isAdmin = true

return (
  <div>
    <p>Hello, {name.toUpperCase()}</p>
    <p>Role: {isAdmin ? 'Admin' : 'User'}</p>
    <p>2 + 2 = {2 + 2}</p>
  </div>
)

The mental shortcut: if it can go on the right-hand side of =, it can go inside {}.

For conditional logic that's too complex for a ternary, compute the value above the return statement and render a variable:

let label
if (score >= 90) label = 'A'
else if (score >= 80) label = 'B'
else label = 'C'

return <p>Grade: {label}</p>

JSX is not HTML — key differences

Interviewers will probe these differences because they catch developers off guard in code reviews.

Attribute name changes:

HTMLJSXWhy
classclassNameclass is a JS reserved word
forhtmlForfor is a JS reserved word
onclickonClickEvents use camelCase
tabindextabIndexMulti-word attributes use camelCase
style="color:red"style={{ color: 'red' }}Style takes a JS object

All tags must close:

// ✅ Self-close when no children
<input type="email" />
<img src="logo.png" alt="Logo" />
<br />

// ❌ Unclosed tags — parse error in JSX
<input type="email">

Case sensitivity: <div> is a DOM element; <Div> would be looked up as a JavaScript variable (a component). Always capitalize custom component names.

Boolean attributes

In HTML, writing disabled as a bare attribute is equivalent to disabled="disabled". JSX follows the same convention — omitting the value sets it to true:

// These are equivalent
<input disabled={true} />
<input disabled />

// Explicitly false — attribute is omitted from the DOM entirely
<input disabled={false} />

The common mistake is disabled="false" — HTML treats any non-empty string as truthy, so the input is still disabled. Always use {false} in JSX.

Inline styles

style takes a JavaScript object with camelCase property names, not a CSS string:

// ❌ HTML string form
<div style="color: red; font-size: 16px">…</div>

// ✅ JSX object form
<div style={{ color: 'red', fontSize: '16px', marginTop: 8 }}>…</div>
//          ^outer: JSX expression  ^inner: object literal

Numbers for pixel-valued properties (marginTop: 8) are converted to 8px automatically. The double-brace {{}} is not special syntax — it's an expression slot {} containing an object literal {}.

Spreading props

Pass a batch of props with {...obj}:

function Button({ size, variant, ...rest }) {
  // size and variant consumed here; everything else forwarded
  return (
    <button
      className={`btn btn-${size} btn-${variant}`}
      {...rest}
    />
  )
}

<Button size="large" variant="primary" aria-label="Save" onClick={save} />

The pattern lets wrapper components be transparent to arbitrary native attributes without listing them explicitly. Destructure known props first and spread the remainder to avoid forwarding internal props to DOM elements.

Comments in JSX

Inside JSX, comments must be wrapped in {} and use block-comment syntax:

return (
  <div>
    {/* This is a JSX comment */}
    <p>Content</p>
    {/* <p>Commented-out element</p> */}
  </div>
)

Standard // comments work fine above the return in regular JavaScript scope.

Rendering arrays and null

React renders arrays of elements as children:

return (
  <ul>
    {items.map(item => <li key={item.id}>{item.name}</li>)}
  </ul>
)

Returning null renders nothing while keeping the component mounted (effects and refs still fire):

function Banner({ show, message }) {
  if (!show) return null
  return <div className="banner">{message}</div>
}

Differences worth knowing: false and undefined render nothing; 0 renders the digit 0 (the classic falsy-zero bug from {count && <Badge />}).

What the interview is really testing

JSX questions are checking whether you know:

  1. JSX compiles to React.createElement (or _jsx with the new transform).
  2. Why attribute names differ from HTML (reserved words, camelCase convention).
  3. How expressions vs statements work inside {}.
  4. Fragment semantics — why they exist and when to use the long form.
  5. Practical pitfalls: boolean attributes as strings, zero in &&, double-brace style objects, self-closing requirements.

Know these and you'll answer JSX questions with confidence rather than guessing.

More ways to practice

The self-quiz is live. Get notified when mock interviews and new question packs drop.

or
Join our WhatsApp Channel