React Tutorial 0/120 lessons ~6 min read Lesson 12

    JSX Basics

    JSX Basics explains JSX syntax, JavaScript expressions, attributes, fragments, events, conditional rendering, list keys, TypeScript type safety, transformation, and declarative React UI design.

    Course progress0%
    Focus
    74 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Learning Objectives

    By the end of this lesson, you will be able to:

    1. Understand what JSX is and why React uses it.
    2. Understand the relationship between JSX and JavaScript.
    3. Write basic JSX syntax correctly.
    4. Embed JavaScript expressions inside JSX.
    5. Understand JSX attributes and their naming conventions.
    6. Use className, htmlFor, and other React-specific attributes.
    7. Render variables and objects safely in JSX.
    8. Understand JSX expressions vs JavaScript statements.
    9. Render multiple elements correctly.
    10. Use React fragments.
    11. Understand JSX nesting rules.
    12. Render conditional UI with JSX.
    13. Render lists with JSX.
    14. Understand JSX event handlers.
    15. Understand how JSX is transformed before reaching the browser.
    16. Understand JSX from a TypeScript perspective.
    17. Identify common JSX mistakes.
    18. Debug JSX effectively.
    19. Explain JSX confidently in React interviews.

    Introduction

    We've now learned:

    text
    React
    ↓
    Vite
    ↓
    Project Structure
    ↓
    SPA
    ↓
    React Developer Tools

    Now we're ready to start writing React UI.

    Consider this React component:

    tsx
    function App() {
    return (
    <h1>Hello React</h1>
    );
    }

    At first glance, this looks like HTML inside JavaScript.

    But it isn't exactly HTML.

    This:

    tsx
    <h1>Hello React</h1>

    is JSX.

    JSX is one of the most important concepts you'll learn in React because almost every React component you build will use it.

    What Is JSX?

    JSX stands for JavaScript XML.

    It is a syntax extension that allows you to write UI-like markup inside JavaScript or TypeScript.

    For example:

    tsx
    const element = <h1>Hello React</h1>;

    JSX lets us express:

    text
    UI structure
    +
    JavaScript logic

    in one place.

    A useful mental model is:

    text
    JS/TS
    +
    JSX
    ↓
    React UI Description

    Why Does React Use JSX?

    Without JSX, React UI can be written using JavaScript function calls.

    Conceptually:

    javascript
    createElement(
    "h1",
    null,
    "Hello React"
    );

    With JSX:

    tsx
    <h1>Hello React</h1>

    The JSX version is much easier to read.

    Imagine a complex UI:

    tsx
    return (
    <div>
    <header>
    <h1>TechLearningPro</h1>
    </header>
    <main>
    <section>
    <h2>React Courses</h2>
    <p>Learn modern React engineering.</p>
    </section>
    </main>
    </div>
    );

    The structure is immediately visible.

    JSX Is Not HTML

    This is one of the first concepts you should remember.

    JSX looks similar to HTML:

    tsx
    <h1>Hello</h1>

    But JSX is part of JavaScript/TypeScript syntax.

    Therefore:

    text
    JSX ≠ HTML

    A better mental model is:

    text
    JSX
    ↓
    JavaScript/TypeScript syntax
    ↓
    React transformation
    ↓
    React elements
    ↓
    DOM updates

    JSX Is Not a Template Language

    Traditional template systems often separate:

    text
    HTML
    CSS
    JavaScript

    React uses a component-oriented approach where UI structure and behavior can live together.

    For example:

    tsx
    function CourseCard({
    title
    }: {
    title: string;
    }) {
    return (
    <article>
    <h2>{title}</h2>
    <button onClick={() => alert(title)}>
    View Course
    </button>
    </article>
    );
    }

    Here we have:

    text
    Markup
    +
    Data
    +
    Behavior

    inside the component.

    Basic JSX Syntax

    The simplest JSX is:

    tsx
    const title = <h1>React</h1>;

    You can create nested elements:

    tsx
    const content = (
    <div>
    <h1>React</h1>
    <p>Learn React step by step.</p>
    </div>
    );

    The parentheses are optional in some situations, but they make multi-line JSX easier to read.

    JSX Must Have One Root

    Consider:

    tsx
    return (
    <h1>React</h1>
    <p>Learn React</p>
    );

    This is invalid JSX because there are two sibling root elements.

    You can wrap them:

    tsx
    return (
    <div>
    <h1>React</h1>
    <p>Learn React</p>
    </div>
    );

    Or use a Fragment:

    tsx
    return (
    <>
    <h1>React</h1>
    <p>Learn React</p>
    </>
    );

    The Fragment doesn't add an extra DOM element.

    React Fragment

    A Fragment allows multiple elements without introducing an additional DOM node.

    tsx
    function App() {
    return (
    <>
    <h1>React</h1>
    <p>Modern frontend engineering</p>
    </>
    );
    }

    Conceptually:

    text
    React Component
    │
    ├── h1
    └── p

    rather than:

    text
    React Component
    │
    └── div
    ├── h1
    └── p

    This can be useful when you don't need a wrapper element.

    Explicit Fragment Syntax

    You can also write:

    tsx
    import { Fragment } from "react";
    return (
    <Fragment>
    <h1>React</h1>
    <p>Learn React</p>
    </Fragment>
    );

    The shorthand:

    tsx
    <>

    is simply a convenient way to write a Fragment.

    JSX Expressions

    One of the most powerful JSX features is embedding JavaScript expressions.

    Use:

    text
    { }

    For example:

    tsx
    const name = "Jagannath";
    return (
    <h1>Hello {name}</h1>
    );

    Output:

    text
    Hello Jagannath

    The important concept is:

    text
    JSX
    +
    { JavaScript expression }

    Variables in JSX

    You can render variables:

    tsx
    const course = "React";
    return (
    <h1>{course}</h1>
    );

    You can also use multiple variables:

    tsx
    const course = "React";
    const level = "Advanced";
    return (
    <div>
    <h1>{course}</h1>
    <p>Level: {level}</p>
    </div>
    );

    Expressions vs Statements

    This is a very important JavaScript concept for JSX.

    Inside {} you can use an expression.

    For example:

    tsx
    {user.name}
    tsx
    {count + 1}
    tsx
    {isLoggedIn ? "Logout" : "Login"}
    tsx
    {items.length}

    But you cannot directly place a normal JavaScript statement there.

    For example, this is invalid:

    tsx
    {
    if (isLoggedIn) {
    return "Welcome";
    }
    }

    Why?

    Because if is a statement, not an expression.

    Instead:

    tsx
    {isLoggedIn ? "Welcome" : "Please login"}

    or move the logic outside JSX.

    JavaScript Expressions You Can Use

    Examples:

    Arithmetic

    tsx
    <p>{10 + 20}</p>

    Result:

    text
    30

    Property access

    tsx
    <p>{user.name}</p>

    Function call

    tsx
    <p>{formatCurrency(price)}</p>

    Ternary

    tsx
    <p>
    {isLoggedIn ? "Welcome" : "Please login"}
    </p>

    Logical AND

    tsx
    {isAdmin && <AdminPanel />}

    These are all expressions.

    JavaScript Inside JSX

    A very common pattern:

    tsx
    function CourseCard({
    course
    }: {
    course: Course;
    }) {
    return (
    <article>
    <h2>{course.title}</h2>
    <p>{course.level}</p>
    <p>{course.price}</p>
    </article>
    );
    }

    The JSX defines the UI structure.

    JavaScript expressions provide the data.

    text
    JSX Structure
    +
    JavaScript Data
    ↓
    Rendered UI

    JSX Attributes

    JSX supports attributes similar to HTML.

    For example:

    tsx
    <img
    src="/logo.png"
    alt="TechLearningPro"
    />

    But JSX uses JavaScript-oriented naming conventions for many attributes.

    For example:

    tsx
    className="course-card"

    instead of:

    html
    class="course-card"

    className

    In HTML:

    html
    <div class="card">

    In JSX:

    tsx
    <div className="card">

    Why?

    Because class has a special meaning in JavaScript syntax, while React uses:

    text
    className

    for the DOM class attribute.

    This is one of the most common differences between HTML and JSX.

    htmlFor

    HTML:

    html
    <label for="email">

    JSX:

    tsx
    <label htmlFor="email">

    Example:

    tsx
    <label htmlFor="email">
    Email
    </label>
    <input
    id="email"
    type="email"
    />

    React follows JavaScript-oriented property naming conventions.

    CamelCase Attributes

    Many JSX attributes use camelCase.

    Examples:

    tsx
    <button
    onClick={handleClick}
    disabled={loading}
    >
    Save
    </button>

    Instead of:

    html
    <button
    onclick="..."
    disabled
    >

    Common JSX attributes include:

    text
    className
    htmlFor
    onClick
    onChange
    onSubmit
    tabIndex
    readOnly
    autoFocus

    JSX Strings

    You can use quotes:

    tsx
    <h1 className="title">
    React
    </h1>

    Or JavaScript expressions:

    tsx
    const className = "title";
    <h1 className={className}>
    React
    </h1>

    These are different syntaxes.

    String literal

    tsx
    className="title"

    JavaScript expression

    tsx
    className={className}

    Dynamic Attributes

    You can dynamically set attributes:

    tsx
    const imageUrl = "/images/react.png";
    <img
    src={imageUrl}
    alt="React"
    />

    You can also calculate them:

    tsx
    const imageUrl =
    isDarkMode
    ? "/images/react-dark.png"
    : "/images/react-light.png";
    <img src={imageUrl} alt="React" />

    This is one of the main advantages of JSX.

    Boolean Attributes

    Some HTML attributes are boolean.

    In JSX:

    tsx
    <button disabled={true}>
    Save
    </button>

    You can simplify:

    tsx
    <button disabled>
    Save
    </button>

    You can also use a variable:

    tsx
    <button disabled={loading}>
    Save
    </button>

    If:

    text
    loading = true

    the button is disabled.

    Event Handlers

    JSX supports React event handlers.

    For example:

    tsx
    function App() {
    function handleClick() {
    console.log("Clicked");
    }
    return (
    <button onClick={handleClick}>
    Click Me
    </button>
    );
    }

    Notice:

    tsx
    onClick={handleClick}

    not:

    tsx
    onClick={handleClick()}

    This distinction is extremely important.

    Function Reference vs Function Call

    Correct:

    tsx
    <button onClick={handleClick}>
    Click
    </button>

    This passes the function.

    Incorrect in most cases:

    tsx
    <button onClick={handleClick()}>
    Click
    </button>

    This calls the function while rendering.

    Mental model:

    text
    onClick={handleClick}
    ↓
    "Run this function when clicked"
    onClick={handleClick()}
    ↓
    "Run this function now"

    Inline Event Handler

    You can also write:

    tsx
    <button
    onClick={() => {
    console.log("Clicked");
    }}
    >
    Click
    </button>

    This is useful when the logic is small.

    For example:

    tsx
    <button
    onClick={() => setCount(count + 1)}
    >
    Increment
    </button>

    Passing Arguments to Events

    Suppose:

    tsx
    function selectCourse(id: string) {
    console.log(id);
    }

    Use:

    tsx
    <button
    onClick={() => selectCourse(course.id)}
    >
    Select
    </button>

    Not:

    tsx
    onClick={selectCourse(course.id)}

    because that would execute during rendering.

    Conditional Rendering

    JSX makes conditional UI straightforward.

    Suppose:

    tsx
    const isLoggedIn = true;

    You can use a ternary:

    tsx
    return (
    <div>
    {isLoggedIn
    ? <Dashboard />
    : <Login />}
    </div>
    );

    Conceptually:

    text
    isLoggedIn?
    │
    ├── true → Dashboard
    └── false → Login

    Logical AND Rendering

    For rendering something only when a condition is true:

    tsx
    {isAdmin && <AdminPanel />}

    If:

    text
    isAdmin = true

    the component renders.

    If:

    text
    isAdmin = false

    it doesn't.

    This pattern is extremely common.

    Important && Pitfall

    Consider:

    tsx
    {items.length && <CourseList />}

    If:

    text
    items.length = 0

    JavaScript evaluates:

    text
    0 && <CourseList />

    which results in:

    text
    0

    That can unexpectedly render 0.

    Safer:

    tsx
    {items.length > 0 && <CourseList />}

    or:

    tsx
    {items.length !== 0 && <CourseList />}

    This is a common JSX interview/debugging question.

    Conditional Rendering With Variables

    For complex logic, move it outside JSX.

    Instead of:

    tsx
    return (
    <div>
    {
    condition1
    ? condition2
    ? ...
    : ...
    : ...
    }
    </div>
    );

    prefer:

    tsx
    let content;
    if (loading) {
    content = <Loading />;
    } else if (error) {
    content = <ErrorMessage />;
    } else {
    content = <CourseList />;
    }
    return (
    <div>
    {content}
    </div>
    );

    This is often much easier to read.

    Rendering Lists

    One of the most common JSX patterns is rendering arrays.

    Suppose:

    tsx
    const courses = [
    "React",
    "Java",
    "Spring Boot"
    ];

    You can write:

    tsx
    <ul>
    {courses.map(course => (
    <li key={course}>
    {course}
    </li>
    ))}
    </ul>

    The important pieces are:

    text
    courses
    ↓
    map()
    ↓
    JSX element for each item

    Why key Matters

    When rendering lists, React needs a stable key.

    Example:

    tsx
    {courses.map(course => (
    <CourseCard
    key={course.id}
    course={course}
    />
    ))}

    The key helps React identify items between renders.

    Think:

    text
    Before
    A
    B
    C
    After
    A
    C
    D

    React needs to understand:

    text
    A → same item
    C → same item
    B → removed
    D → new

    Stable keys help React reason about these changes.

    We'll study keys and reconciliation in more depth later.

    Don't Use Array Index as Key Automatically

    You might see:

    tsx
    {courses.map((course, index) => (
    <CourseCard
    key={index}
    course={course}
    />
    ))}

    This can be acceptable for truly static lists, but it can cause problems when items are:

    text
    Added
    Removed
    Reordered
    Filtered

    Prefer a stable identifier:

    tsx
    key={course.id}

    when one exists.

    JSX Comments

    You cannot normally use HTML comments:

    tsx
    <!-- Comment -->

    Instead:

    tsx
    {/* Comment */}

    Example:

    tsx
    return (
    <div>
    {/* Course title */}
    <h1>{course.title}</h1>
    </div>
    );

    Remember:

    text
    JSX comment
    → {/* ... */}

    Self-Closing Elements

    JSX requires elements without children to be properly closed.

    HTML sometimes allows:

    html
    <img src="logo.png">

    JSX should use:

    tsx
    <img src="logo.png" />

    Similarly:

    tsx
    <input />
    <br />
    <hr />
    <img />

    This is a common JSX syntax requirement.

    Nested Elements

    JSX nesting must follow valid structure.

    For example:

    tsx
    <div>
    <section>
    <h1>React</h1>
    <p>Learn JSX</p>
    </section>
    </div>

    You can nest components:

    tsx
    <App>
    <Header />
    <Main />
    <Footer />
    </App>

    Components are treated like JSX elements.

    Custom Components

    HTML elements are lowercase:

    tsx
    <div />
    <button />
    <section />

    React components conventionally begin with uppercase letters:

    tsx
    <CourseCard />
    <Header />
    <Navigation />

    This naming convention is significant.

    React can distinguish:

    text
    div

    from:

    text
    CourseCard

    as different kinds of JSX elements.

    Component Props in JSX

    Suppose:

    tsx
    function CourseCard({
    title,
    level
    }: {
    title: string;
    level: string;
    }) {
    return (
    <article>
    <h2>{title}</h2>
    <p>{level}</p>
    </article>
    );
    }

    Use:

    tsx
    <CourseCard
    title="React"
    level="Advanced"
    />

    Here:

    text
    title="React"

    is a JSX prop.

    Dynamic Props

    You can pass JavaScript values:

    tsx
    const title = "React";
    const level = "Advanced";
    <CourseCard
    title={title}
    level={level}
    />

    Or:

    tsx
    <CourseCard
    title={course.title}
    level={course.level}
    />

    The braces mean:

    Evaluate this JavaScript expression.

    String vs Expression Props

    These are different:

    tsx
    <CourseCard title="React" />

    and:

    tsx
    <CourseCard title={"React"} />

    Both ultimately provide a string.

    But:

    tsx
    <CourseCard title={course.title} />

    uses a JavaScript expression.

    Similarly:

    tsx
    <CourseCard level="1" />

    passes a string:

    text
    "1"

    while:

    tsx
    <CourseCard level={1} />

    passes a number:

    text
    1

    This distinction matters in TypeScript.

    JSX With TypeScript

    React projects commonly use:

    text
    .tsx

    instead of:

    text
    .ts

    when the file contains JSX.

    Example:

    tsx
    interface Course {
    id: string;
    title: string;
    }
    function CourseCard({
    course
    }: {
    course: Course;
    }) {
    return (
    <article>
    <h2>{course.title}</h2>
    </article>
    );
    }

    The .tsx extension tells TypeScript tooling that JSX syntax is allowed in the file.

    JSX and Type Safety

    TypeScript can catch incorrect props.

    Suppose:

    tsx
    interface CourseCardProps {
    title: string;
    level: "Beginner" | "Intermediate" | "Advanced";
    }

    Then:

    tsx
    <CourseCard
    title="React"
    level="Expert"
    />

    can produce a TypeScript error because:

    text
    "Expert"

    is not part of the allowed union.

    This is one of the major benefits of React + TypeScript.

    JSX Expressions With Objects

    You can access object properties:

    tsx
    const course = {
    title: "React",
    level: "Advanced"
    };
    return (
    <div>
    <h1>{course.title}</h1>
    <p>{course.level}</p>
    </div>
    );

    But you generally cannot directly render a plain object:

    tsx
    <div>{course}</div>

    That will not produce useful UI and can result in a runtime error because React cannot render an arbitrary object as a child.

    Instead:

    tsx
    <div>{course.title}</div>

    Rendering Arrays

    Arrays can be rendered when their contents are renderable:

    tsx
    const names = ["Java", "React", "Angular"];
    return (
    <div>
    {names}
    </div>
    );

    For structured UI, map() is usually clearer:

    tsx
    <ul>
    {names.map(name => (
    <li key={name}>{name}</li>
    ))}
    </ul>

    Rendering null

    React allows:

    tsx
    return null;

    A component returning null renders nothing.

    This can be useful:

    tsx
    function AdminPanel({
    isAdmin
    }: {
    isAdmin: boolean;
    }) {
    if (!isAdmin) {
    return null;
    }
    return <section>Admin</section>;
    }

    However, remember that backend authorization is still required for security.

    Rendering false

    Values such as:

    text
    false
    null
    undefined

    are generally not rendered as visible text by React.

    That's why this works:

    tsx
    {isLoggedIn && <Dashboard />}

    When isLoggedIn is false, React doesn't render the boolean itself.

    Be careful with other falsy values such as 0.

    JSX and Whitespace

    JSX whitespace behavior isn't exactly the same as writing raw HTML.

    For example:

    tsx
    <p>
    Hello
    React
    </p>

    shouldn't be treated as a way to precisely control text formatting.

    For deliberate spacing, you can use:

    tsx
    <p>
    Hello{" "}
    {name}
    </p>

    or structure the markup appropriately.

    JSX and HTML Entities

    You can use normal HTML entities when needed:

    tsx
    <p>
    React &amp; TypeScript
    </p>

    You can also use JavaScript strings/expressions when appropriate.

    The important point is that JSX is processed as JavaScript syntax, not simply pasted into the browser as raw HTML.

    JSX Transformation

    Now let's understand what happens behind the scenes.

    You write:

    tsx
    function App() {
    return <h1>Hello React</h1>;
    }

    The JSX must be transformed before the browser executes it.

    Conceptually:

    text
    JSX
    ↓
    JS Transformation
    ↓
    React Element Creation
    ↓
    React
    ↓
    DOM

    Modern React tooling uses the JSX transform to convert JSX into JavaScript calls.

    Old JSX Transformation

    Historically, developers often saw code conceptually transformed into:

    javascript
    React.createElement(
    "h1",
    null,
    "Hello React"
    );

    This is why older React tutorials sometimes required:

    tsx
    import React from "react";

    in every JSX file.

    With the modern JSX transform, that import is generally not required simply to use JSX.

    Modern JSX Transform

    Modern React tooling can transform:

    tsx
    <h1>Hello</h1>

    using the newer JSX runtime.

    Conceptually:

    text
    JSX
    ↓
    jsx(...)
    ↓
    React element

    You don't need to manually write these transformation calls.

    Vite, TypeScript, and the React tooling cooperate to provide the required development experience.

    JSX Is Declarative

    One of the most important conceptual ideas is that JSX describes what the UI should look like, rather than manually instructing the browser how to update every DOM node.

    Instead of:

    javascript
    const heading = document.createElement("h1");
    heading.textContent = "React";
    document.body.appendChild(heading);

    you write:

    tsx
    <h1>React</h1>

    React manages the rendering process.

    Imperative vs Declarative

    Imperative

    text
    Create element
    ↓
    Set text
    ↓
    Set class
    ↓
    Append element
    ↓
    Update element
    ↓
    Remove element

    Declarative

    text
    State
    ↓
    Desired UI
    ↓
    React
    ↓
    DOM

    React encourages the declarative approach.

    JSX With State

    Consider:

    tsx
    function Counter() {
    const [count, setCount] = useState(0);
    return (
    <div>
    <p>Count: {count}</p>
    <button
    onClick={() => setCount(count + 1)}
    >
    Increment
    </button>
    </div>
    );
    }

    Notice the relationship:

    text
    State
    ↓
    JSX
    ↓
    UI

    When state changes:

    text
    count = 0
    ↓
    count = 1
    ↓
    JSX produces updated UI

    This is the foundation of React's programming model.

    JSX With Conditional State

    For example:

    tsx
    function LoginStatus({
    isLoggedIn
    }: {
    isLoggedIn: boolean;
    }) {
    return (
    <div>
    {isLoggedIn
    ? <Dashboard />
    : <Login />}
    </div>
    );
    }

    The UI becomes a function of state:

    text
    UI = f(state)

    This is a useful conceptual model for React.

    JSX and Data Flow

    Consider:

    text
    API
    ↓
    State
    ↓
    Component
    ↓
    JSX
    ↓
    UI

    For example:

    tsx
    function CoursePage() {
    const { course } = useCourse();
    return (
    <main>
    <h1>{course.title}</h1>
    <p>{course.description}</p>
    </main>
    );
    }

    JSX becomes the bridge between:

    text
    Application Data

    and:

    text
    Rendered UI

    JSX and Event Flow

    The reverse direction is also important:

    text
    User
    ↓
    Event
    ↓
    Handler
    ↓
    State Update
    ↓
    Render
    ↓
    JSX
    ↓
    Updated UI

    Example:

    tsx
    <button
    onClick={() => setCount(count + 1)}
    >
    {count}
    </button>

    This creates the fundamental React loop:

    text
    User Action
    ↓
    State Change
    ↓
    Render
    ↓
    Updated UI

    Common JSX Mistakes

    Mistake 1: Using class

    Incorrect:

    tsx
    <div class="card">

    Correct:

    tsx
    <div className="card">

    Mistake 2: Multiple Root Elements

    Incorrect:

    tsx
    return (
    <h1>Hello</h1>
    <p>React</p>
    );

    Correct:

    tsx
    return (
    <>
    <h1>Hello</h1>
    <p>React</p>
    </>
    );

    Mistake 3: Forgetting Closing Tags

    Incorrect:

    tsx
    <input>

    Correct:

    tsx
    <input />

    Mistake 4: Calling Event Handlers Immediately

    Incorrect:

    tsx
    onClick={handleClick()}

    Correct:

    tsx
    onClick={handleClick}

    or:

    tsx
    onClick={() => handleClick()}

    Mistake 5: Using if Directly Inside JSX

    Incorrect:

    tsx
    {
    if (isLoggedIn) {
    return <Dashboard />;
    }
    }

    Use:

    tsx
    {isLoggedIn && <Dashboard />}

    or a ternary.

    Common Mistake: Incorrect Component Name

    Incorrect:

    tsx
    <courseCard />

    React treats lowercase JSX names as intrinsic elements.

    Correct:

    tsx
    <CourseCard />

    Use PascalCase for React components.

    Common Mistake: Rendering Objects

    Incorrect:

    tsx
    <p>{user}</p>

    If user is an object, this isn't valid as a normal React child.

    Use:

    tsx
    <p>{user.name}</p>

    or explicitly transform the data.

    Common Mistake: Missing Keys

    Incorrect:

    tsx
    {courses.map(course => (
    <CourseCard course={course} />
    ))}

    Correct:

    tsx
    {courses.map(course => (
    <CourseCard
    key={course.id}
    course={course}
    />
    ))}

    Keys help React identify list items.

    Common Mistake: Putting Too Much Logic in JSX

    This can become difficult to read:

    tsx
    return (
    <div>
    {loading
    ? <Loading />
    : error
    ? <Error />
    : courses.length === 0
    ? <Empty />
    : courses.map(...)}
    </div>
    );

    Instead, extract logic:

    tsx
    if (loading) {
    return <Loading />;
    }
    if (error) {
    return <Error />;
    }
    if (courses.length === 0) {
    return <Empty />;
    }
    return <CourseList courses={courses} />;

    Readable code is a performance feature for developers.

    Practical Exercise 1 — Basic JSX

    Create:

    tsx
    function App() {
    const name = "Jagannath";
    const course = "React";
    return (
    <main>
    <h1>Welcome, {name}</h1>
    <p>You are learning {course}.</p>
    </main>
    );
    }

    Observe how:

    text
    name
    course

    are inserted into JSX.

    Practical Exercise 2 — Dynamic Attributes

    Create:

    tsx
    function CourseImage() {
    const imageUrl =
    "/images/react-course.png";
    return (
    <img
    src={imageUrl}
    alt="React Course"
    />
    );
    }

    Now change imageUrl dynamically.

    Practical Exercise 3 — Conditional Rendering

    Create:

    tsx
    function AuthStatus({
    isLoggedIn
    }: {
    isLoggedIn: boolean;
    }) {
    return (
    <section>
    {isLoggedIn
    ? <h2>Welcome back!</h2>
    : <h2>Please login.</h2>}
    </section>
    );
    }

    Test:

    tsx
    <AuthStatus isLoggedIn={true} />

    and:

    tsx
    <AuthStatus isLoggedIn={false} />

    Practical Exercise 4 — List Rendering

    Create:

    tsx
    const courses = [
    {
    id: 1,
    title: "React"
    },
    {
    id: 2,
    title: "Java"
    },
    {
    id: 3,
    title: "Spring Boot"
    }
    ];

    Render:

    tsx
    <ul>
    {courses.map(course => (
    <li key={course.id}>
    {course.title}
    </li>
    ))}
    </ul>

    Observe how the array becomes UI.

    Practical Exercise 5 — Event Handling

    Create:

    tsx
    function Counter() {
    const [count, setCount] = useState(0);
    return (
    <section>
    <p>Count: {count}</p>
    <button
    onClick={() => setCount(count + 1)}
    >
    Increment
    </button>
    </section>
    );
    }

    The flow is:

    text
    Click
    ↓
    setCount()
    ↓
    State changes
    ↓
    Component renders
    ↓
    JSX updates UI

    This is the core React mental model.

    Practical Exercise 6 — Course Card

    Build a realistic component:

    tsx
    interface Course {
    id: string;
    title: string;
    description: string;
    level: "Beginner" | "Intermediate" | "Advanced";
    }
    function CourseCard({
    course
    }: {
    course: Course;
    }) {
    return (
    <article className="course-card">
    <h2>{course.title}</h2>
    <p>
    {course.description}
    </p>
    <span>
    {course.level}
    </span>
    <button>
    View Course
    </button>
    </article>
    );
    }

    This combines:

    text
    TypeScript
    +
    Props
    +
    JSX
    +
    Expressions
    +
    Attributes

    Interview questions & answers

    Interview preparation

    14 questions grouped by difficulty — expand any card for a model answer and follow-up probe.

    Beginner

    4
    1. 1What is JSX?
      Beginner

      Model answer

      JSX is a syntax extension that allows us to write UI-like markup inside JavaScript or TypeScript.

      It makes React component structure easier to express and is transformed into JavaScript that React can process.

    2. 2Is JSX HTML?
      Beginner

      Model answer

      No.

      JSX looks similar to HTML, but it is JavaScript/TypeScript syntax used to describe React UI.

    3. 3Why do we use className instead of class?
      Beginner

      Model answer

      JSX follows JavaScript-oriented property naming, and React uses className to represent the DOM class attribute.
    4. 4What does {} mean in JSX?
      Beginner

      Model answer

      Curly braces allow JavaScript expressions to be embedded inside JSX.

    Intermediate

    4
    1. 5Can we use if directly inside JSX?
      Intermediate

      Model answer

      No, not as a direct JSX expression because if is a statement. We can use a ternary expression, logical operators, or calculate the content before returning JSX.
    2. 6What is the difference between:
      Intermediate

      Model answer

      onClick={handleClick} and: onClick={handleClick()} The first passes the function reference to React so it can be executed when the event occurs. The second executes the function during rendering and passes its result to onClick.
    3. 7Why does JSX require a single root?
      Intermediate

      Model answer

      A component's JSX return must represent a single element/tree.

      A Fragment can be used when we need multiple sibling elements without adding an extra DOM node.

    4. 8Why are keys required when rendering lists?
      Intermediate

      Model answer

      Keys provide stable identity for list items, helping React determine which items were added, removed, or changed between renders.

    Advanced

    6
    1. 9What happens to JSX before it reaches the browser?
      Advanced

      Model answer

      JSX is transformed by the React/JavaScript build tooling into JavaScript that describes React elements.

      React then uses that representation during its rendering process and commits necessary changes to the DOM.

    2. 10Why is JSX considered declarative?
      Advanced

      Model answer

      JSX describes the desired UI based on the current application state rather than manually instructing the browser how to create, update, and remove individual DOM elements.

    3. 11Is JSX required to use React?
      Advanced

      Model answer

      No.

      React can be used without JSX by writing JavaScript calls directly.

      JSX is primarily a more readable syntax for expressing React UI.

    4. 12Why does JSX improve maintainability?
      Advanced

      Model answer

      JSX allows component structure, dynamic data, and event behavior to be expressed close together.

      This improves readability and makes the relationship between application state and UI easier to understand.

    5. 13Does JSX directly manipulate the DOM?
      Advanced

      Model answer

      No.

      JSX describes the UI.

      React processes the resulting element representation and manages the necessary DOM updates.

    6. 14How would you prevent JSX from becoming difficult to maintain?
      Advanced

      Model answer

      I'd keep components focused, move complex business logic outside the JSX, extract reusable components, avoid deeply nested conditional expressions, use clear naming, and keep feature-specific behavior close to its feature.

    Important Architecture Connection

    Let's connect everything we've learned.

    We started with:

    text
    React

    Then:

    text
    Vite

    Then:

    text
    Folder Structure

    Then:

    text
    SPA

    Then:

    text
    React Developer Tools

    Now:

    text
    JSX

    The complete mental model is becoming:

    text
    React Application
    │
    ▼
    JSX
    │
    ▼
    React Element Tree
    │
    ▼
    React Rendering
    │
    ▼
    DOM
    │
    ▼
    Browser

    And application interaction flows backward:

    text
    User
    ↓
    Event
    ↓
    Handler
    ↓
    State Update
    ↓
    React Render
    ↓
    JSX
    ↓
    Updated UI

    This is the foundation of React engineering.

    JSX in an Enterprise Application

    Consider our TechLearningPro-style architecture:

    text
    features/
    └── courses/
    ├── components/
    │ └── CourseCard.tsx
    ├── hooks/
    │ └── useCourses.ts
    ├── services/
    │ └── courseService.ts
    └── types/
    └── course.types.ts

    The data flow becomes:

    text
    Spring Boot API
    │
    ▼
    courseService
    │
    ▼
    useCourses()
    │
    ▼
    CoursePage
    │
    ▼
    CourseList
    │
    ▼
    CourseCard
    │
    ▼
    JSX
    │
    ▼
    Browser UI

    JSX is the final declarative representation of the UI at the component level.

    The Most Important JSX Mental Model

    Don't think:

    JSX is HTML inside JavaScript.

    That's a beginner-level description.

    Think:

    JSX is a declarative syntax for describing the React UI tree using JavaScript/TypeScript expressions.

    Therefore:

    text
    State
    ↓
    Component Logic
    ↓
    JSX
    ↓
    React Elements
    ↓
    Reconciliation
    ↓
    DOM
    ↓
    Browser

    This mental model will become extremely important when we study:

    text
    Props
    State
    Events
    Rendering
    Reconciliation
    Virtual DOM
    Hooks
    Performance

    Final Mental Model

    Remember this:

    text
    USER
    │
    ▼
    Event
    │
    ▼
    Event Handler
    │
    ▼
    State Update
    │
    ▼
    Component Re-render
    │
    ▼
    JSX
    │
    ▼
    React Element Tree
    │
    ▼
    Reconciliation
    │
    ▼
    DOM Updates
    │
    ▼
    Browser

    And the key equation:

    text
    UI = f(State)

    Meaning:

    The UI is a function of the current application state.

    JSX is the language-like syntax we use to express that UI.

    Next Lesson

    JSX Expressions and JavaScript

    We'll go deeper into the most powerful part of JSX:

    text
    JSX
    │
    ├── Variables
    ├── Expressions
    ├── Function Calls
    ├── Object Properties
    ├── Ternary Operators
    ├── && Operator
    ├── Arrays
    ├── map()
    ├── Conditional UI
    ├── Derived Values
    └── Common Expression Pitfalls

    We'll also cover what can and cannot be placed inside {}, which is one of the most important JSX concepts for becoming comfortable with React.

    Ready to mark this lesson complete?Track your journey across the entire course.