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
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>;
}
Class Components (Legacy React < 16.8)
ES6 classes extending React.Component
- Requires
class ... extends React.Component. - Mandates boilerplate:
this.state,this.props, and explicitrender()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!'
}
}
3. The 5 Golden Rules of JSX
Because JSX is transpiled directly into JavaScript function calls, it obeys strict syntactic rules:
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>
</>
);
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 />
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 />
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>
);
}
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>
);
}
Anshuman Singh
Initials: A.S. | Points to Next Tier: 5 pts
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>
);
}
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!
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).
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 withcolor('#10B981' or '#F59E0B') andfontWeight: 'bold'.
{ header: "ANSHUMAN SINGH (Age: 22)", statusBadge: "PASSED (Green)", displayStyle: { color: "#10B981", fontWeight: "bold" } }
formatUserProfile and click "▶ Run Code" to check the output.
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.
- Set
$$typeof: Symbol.for('react.element'). - Set
type: tag,key: attributes.key || null,ref: attributes.ref || null. - Return all attributes spread inside
propswithchildrenincluded.
{ type: "div", key: null, ref: null, props: { className: "card", children: "Card Body" } }
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.
- Check for
class=and push warning to useclassName. - Check for
for=and push warning to usehtmlFor. - Check for unclosed void tags (
img,input,br,hr) without/>. - Return '✅ Valid JSX Syntax!' if no errors found.
Audit A: ["Error: Use className instead of class...", ...] | Audit B: "✅ Valid JSX Syntax!"
validateJSXRules and click "▶ Run Code".