React

Chapter 02: Components & JSX — Functional components, JSX compilation, syntax rules, dynamic expressions, fragments, and children composition.

1. What is a Component?

A Component is a self-contained, independent, and reusable piece of user interface. Think of components as custom HTML elements with their own logic, appearance, and lifecycle.

💡 Real-World Analogy: Lego Bricks & Modular Architecture

Building a modern React application is like assembling a castle from Lego bricks:

  • Instead of writing one giant 2,000-line HTML file, you build small, specialized bricks: <Navbar />, <Sidebar />, <ProductCard />, and <Footer />.
  • If a product card needs a design update, you edit that single component file once, and all 50 product cards across your entire e-commerce store update instantly!

Functional Components vs Legacy Class Components

01

Functional Components (Modern Standard)

Plain JavaScript functions that return JSX

  • Uses standard JavaScript functions or arrow functions.
  • Employs React Hooks (like useState, useEffect) for state and lifecycle.
  • Clean, concise, and standard across 100% of modern codebases.
function Welcome(props) {
    return <h1>Hello, {props.name}!</h1>;
}
02

Class Components (Legacy React < 16.8)

ES6 classes extending React.Component

  • Requires class ... extends React.Component.
  • Mandates boilerplate: this.state, this.props, and explicit render() methods.
  • Legacy syntax; rarely used in new React 18+ code.
class Welcome extends React.Component {
    render() {
        return <h1>Hello, {this.props.name}!</h1>;
    }
}

2. What is JSX? (JavaScript XML)

JSX stands for JavaScript XML. It is a syntax extension for JavaScript that looks similar to HTML, allowing you to write your UI structure right alongside your component logic.

🔍 What Happens to JSX Under the Hood?

Browsers cannot understand JSX directly! Compilers like Babel or Vite (esbuild) transform your JSX into plain React.createElement() function calls:

// 1. What you write in JSX:
const element = <h1 className="title">Hello React!</h1>;

// 2. What the compiler outputs (compiled JavaScript):
const element = React.createElement(
    'h1',
    { className: 'title' },
    'Hello React!'
);

// 3. What React.createElement produces (a Virtual DOM JavaScript object):
{
    type: 'h1',
    props: {
        className: 'title',
        children: 'Hello React!'
    }
}
Compiled JavaScript Engine Output:
{ "type": "h1", "props": { "className": "title", "children": "Hello React!" } }

3. The 5 Golden Rules of JSX

Because JSX is transpiled directly into JavaScript function calls, it obeys strict syntactic rules:

01

1. Return a Single Root Element

A component can only return one top-level element. If returning multiple adjacent tags, wrap them in a React Fragment (<>...</>) to avoid cluttering the DOM with useless wrapper <div> nodes.

// ✅ Valid Fragment syntax:
return (
    <>
        <h1>Title</h1>
        <p>Paragraph</p>
    </>
);
02

2. PascalCase Component Names

Component names must start with a capital letter (e.g., <UserProfile />). Lowercase tags (like <div>, <span>) are treated as standard native HTML elements.

function MyButton() { // Capital "M"
    return <button>Click</button>;
}
// Usage: <MyButton />
03

3. Explicitly Close All Tags

Unlike standard HTML, self-closing tags in JSX must always have a closing forward slash />.

<img src="avatar.png" alt="User" />
<input type="text" placeholder="Name" />
<br /> <hr />
04

4. Special Reserved HTML Attributes

Because class and for are reserved keywords in JavaScript, JSX uses className and htmlFor.

// className instead of class
<div className="card-box">
// htmlFor instead of for
<label htmlFor="email">Email</label>
<input id="email" />

🎨 Rule 5: Inline Styles Use CamelCase JavaScript Objects

In HTML, styles are written as strings: style="font-size: 16px; background-color: blue;".
In JSX, the style attribute accepts a JavaScript object. That's why you see double curly braces {{ }} (the outer brace enters JavaScript mode, and the inner brace defines the object literal):

const cardStyles = {
    backgroundColor: "#F0EBFF", // camelCase instead of background-color
    fontSize: "18px",           // camelCase instead of font-size
    padding: "20px",
    borderRadius: "12px"        // camelCase instead of border-radius
};

function StyledCard() {
    return (
        <div style={{ backgroundColor: "#F0EBFF", padding: "16px", borderRadius: "8px" }}>
            <h3 style={{ color: "#6C4CE8", margin: 0 }}>Custom Styled Card</h3>
        </div>
    );
}
Rendered Component Preview:

Custom Styled Card

4. Dynamic JavaScript in JSX with Curly Braces { }

Whenever you want to switch from writing markup to evaluating JavaScript, wrap the expression in single curly braces { }. You can embed variables, object properties, array operations, arithmetic, and ternary expressions:

function UserGreeting() {
    const user = { firstName: "Anshuman", lastName: "Singh", score: 95 };
    const isPremium = true;
    const notifications = ["New message", "System update", "Course unlocked"];

    return (
        <div className="user-profile-card">
            {/* 1. Variable & Property Interpolation */}
            <h2>{user.firstName} {user.lastName}</h2>
            
            {/* 2. JavaScript String Methods & Math Calculations */}
            <p>Initials: {user.firstName[0]}.{user.lastName[0]}.</p>
            <p>Points to Next Tier: {100 - user.score} pts</p>

            {/* 3. Dynamic Conditional Ternary Expression */}
            <span className={isPremium ? "badge-gold" : "badge-standard"}>
                {isPremium ? "⭐ Premium Member" : "Standard Tier"}
            </span>

            {/* 4. Reading Array Length */}
            <p>You have {notifications.length} pending alerts.</p>
        </div>
    );
}
Evaluated JSX Render:

Anshuman Singh

Initials: A.S. | Points to Next Tier: 5 pts

⭐ Premium Member

You have 3 pending alerts.

5. Component Composition & The children Prop

Components can wrap other arbitrary JSX elements or nested components using the special props.children identifier. This enables building reusable container wrappers (Cards, Modals, Accordions, Page Layouts):

// 1. Reusable Container Component
function ModalDialog({ title, isOpen, children }) {
    if (!isOpen) return null;

    return (
        <div className="modal-backdrop">
            <div className="modal-content">
                <div className="modal-header">
                    <h3>{title}</h3>
                </div>
                <div className="modal-body">
                    {/* Nested content passed between <ModalDialog>...</ModalDialog> */}
                    {children}
                </div>
            </div>
        </div>
    );
}

// 2. Usage: Injecting any custom JSX into the children slot
function App() {
    return (
        <ModalDialog title="Confirm Enrollment" isOpen={true}>
            <p>Are you ready to begin the React Mastery Track?</p>
            <button className="confirm-btn">Yes, Let's Go!</button>
        </ModalDialog>
    );
}
Rendered Modal Preview:

Confirm Enrollment

Are you ready to begin the React Mastery Track?

6. Top Interview Questions & Common Pitfalls

⚠️ Pitfall 1: "Why can't I write an if-statement inside JSX curly braces { }?"

The Explanation: Inside { }, JSX only accepts JavaScript Expressions (code that evaluates to a return value, like user.name, 2 + 2, or isLoggedIn ? 'A' : 'B'). An if/else or for loop is a Statement (action instruction) that does not evaluate to a value. To conditionally render in JSX, use Ternary operators (? :) or Logical AND (&&).

⚠️ Pitfall 2: "What is the difference between <MyComponent /> and MyComponent()?"

The Explanation: Always invoke components with JSX syntax <MyComponent />! When written in JSX, React registers the component in its Fiber node hierarchy, tracks hook state across renders, and coordinates lifecycle effects. Invoking it as a normal function MyComponent() bypasses React's reconciler and breaks Hook execution rules.

7. Hands-On Practice Challenges

Sharpen your JSX and component development skills with these hands-on challenges. Click "Solve Challenge" to open the code editor!

🎯 Hands-on Coding Challenge JSX Transformations

Challenge 1: JSX Dynamic Expression Formatter

Write a helper function formatUserProfile(user) that accepts a user object (name, age, score) and returns an object representing the evaluated dynamic text, status badge, and camelCase style object (e.g. green if score $\ge 80$, amber otherwise).

📋 Requirements & What to Write:
  • header: Uppercase user name with age in parentheses (e.g., "ANSHUMAN SINGH (Age: 22)").
  • statusBadge: Return "PASSED (Green)" if score $\ge 80$, else "NEEDS IMPROVEMENT (Amber)".
  • displayStyle: Return an object with color ('#10B981' or '#F59E0B') and fontWeight: 'bold'.
Expected Result: { header: "ANSHUMAN SINGH (Age: 22)", statusBadge: "PASSED (Green)", displayStyle: { color: "#10B981", fontWeight: "bold" } }
💡
Editor Instructions: Complete formatUserProfile and click "▶ Run Code" to check the output.
profileFormatter.js
Console / Terminal Output
// Output will appear here when you click "Run Code"...
🎯 Hands-on Coding Challenge Compiler Architecture

Challenge 2: Build a JSX Transpiler Simulator

Recreate Babel's JSX transformation by writing simulateBabelJSX(tag, attributes, ...children) that converts input arguments into a valid React element object with $$typeof, type, and props.

📋 Requirements & What to Write:
  • Set $$typeof: Symbol.for('react.element').
  • Set type: tag, key: attributes.key || null, ref: attributes.ref || null.
  • Return all attributes spread inside props with children included.
Expected Result: { type: "div", key: null, ref: null, props: { className: "card", children: "Card Body" } }
💡
Editor Instructions: Recreate the exact React element data structure.
babelTranspiler.js
Console / Terminal Output
// Output will appear here when you click "Run Code"...
🎯 Hands-on Coding Challenge Linter & Static Analysis

Challenge 3: JSX Syntax Linter & Rule Auditor

Write a linter function validateJSXRules(componentString) that scans markup text and catches illegal usage of class= (should be className), for= (should be htmlFor), or unclosed <img> / <input> tags.

📋 Requirements & What to Write:
  • Check for class= and push warning to use className.
  • Check for for= and push warning to use htmlFor.
  • Check for unclosed void tags (img, input, br, hr) without />.
  • Return '✅ Valid JSX Syntax!' if no errors found.
Expected Result: Audit A: ["Error: Use className instead of class...", ...] | Audit B: "✅ Valid JSX Syntax!"
💡
Editor Instructions: Implement syntax checks in validateJSXRules and click "▶ Run Code".
jsxLinter.js
Console / Terminal Output
// Output will appear here when you click "Run Code"...