Introduction
In Part 1, we learned that React is a JavaScript library for building UIs using components — small, reusable pieces that describe what the screen should look like. We also saw some code that looked like HTML sitting right inside JavaScript.
That "HTML-like" syntax is called JSX, and it's one of the first things that surprises new React developers. It's not HTML. It's not a template language. It's JavaScript in disguise.
In this part, we'll break down exactly how JSX works, learn its rules, and build properly structured React components from scratch.
What is JSX?
JSX stands for JavaScript XML. It's a syntax extension that lets you write HTML-like code inside JavaScript files.
javascript
This looks like HTML, but it's actually syntactic sugar for a JavaScript function call. Behind the scenes, the JSX compiler (Babel) transforms it into:
javascript
React.createElement creates a plain JavaScript object — a React element — that describes what should appear on screen. React reads these objects and uses them to build and update the DOM.
Why Not Just Use createElement Directly?
You can, but it gets unreadable fast:
javascript
JSX exists to make your code readable. It compiles down to createElement calls anyway, so there's no performance difference.
JSX Rules You Must Know
JSX looks like HTML, but it has its own rules. Breaking these rules causes errors, so let's go through each one.
1. Return a Single Root Element
A component must return one root element. This won't work:
javascript
Fix it by wrapping in a <div> or a Fragment (<>...</>):
javascript
Fragments (<>...</>) let you group elements without adding an extra <div> to the DOM.
2. Close All Tags
In HTML, some tags are self-closing (<img>, <br>, <input>). In JSX, every tag must be explicitly closed:
javascript
3. Use className Instead of class
Since class is a reserved word in JavaScript, JSX uses className:
javascript
4. Use htmlFor Instead of for
Similarly, for is reserved, so labels use htmlFor:
javascript
5. CamelCase for Event Handlers and Attributes
HTML uses lowercase (onclick, tabindex). JSX uses camelCase (onClick, tabIndex):
javascript
6. Use Curly Braces {} for JavaScript Expressions
Curly braces let you embed any JavaScript expression inside JSX:
javascript
You can put variables, math, function calls, ternary operators — any expression that produces a value. But you cannot put statements like if/else or for loops directly inside {}.
Expressions vs Statements in JSX
This distinction trips up many beginners:
javascript
For conditional rendering, use ternaries or logical AND:
javascript
Building Components
A React component is a JavaScript function that returns JSX. There are a few conventions to follow.
Component Names Must Be Capitalized
React uses capitalization to distinguish between HTML elements and components:
javascript
If you name a component header (lowercase), React will try to render an HTML <header> tag instead of your component.
Function Components
The modern way to write React components is as functions:
javascript
Both are identical. Use whichever style your team prefers.
Nesting Components
Components can render other components. This is how you build complex UIs from simple pieces:
javascript
Header doesn't need to know how Logo or Navigation work internally. It just uses them. This separation of concerns is what makes React scalable.
Putting It Together: A Profile Card
Let's build a real component that uses everything we've learned. This interactive example renders a profile card with dynamic data, conditional rendering, and nested components:
Preview
What this demonstrates:
- Nested components —
ProfileCardusesAvatar,StatusBadge,Stat, andSkillTag - Dynamic data — Everything renders from the
userobject using{} - Conditional rendering —
StatusBadgeshows green or gray based onisOnline - List rendering —
user.skills.map()renders aSkillTagfor each skill - The
keyprop — When rendering lists, each item needs a uniquekeyso React can track them
Rendering Lists with .map()
One of the most common patterns in React is rendering a list of items. You use JavaScript's .map() method:
javascript
Why Do We Need key?
The key prop helps React identify which items changed, were added, or removed. Without keys, React has to re-render the entire list every time. With keys, it only updates what changed.
Rules for keys:
- Must be unique among siblings (not globally)
- Must be stable — don't use array indexes if the list can reorder
- Should come from your data (IDs, slugs, etc.)
javascript
Inline Styles in JSX
In HTML, you write style="color: red; font-size: 14px". In JSX, style takes a JavaScript object with camelCase properties:
javascript
The double curly braces look odd at first: the outer {} says "JavaScript expression incoming", and the inner {} is the object literal.
Note: In real projects, you'll usually use CSS classes (via
className) or a CSS-in-JS solution like Tailwind instead of inline styles. Inline styles are fine for quick prototypes or truly dynamic values.
Common Mistakes
1. Forgetting Curly Braces
javascript
2. Using class Instead of className
javascript
3. Returning Multiple Root Elements
javascript
4. Forgetting key in Lists
React will warn you in the console. Always add a key when using .map() to render elements.
JSX is Just JavaScript
This is the most important takeaway: JSX is not a separate language. It's JavaScript with a convenient syntax for describing UI. Everything compiles to React.createElement calls, which produce plain objects.
This means you can:
- Store JSX in variables:
const header = <h1>Hello</h1>; - Return JSX from functions (that's what components are)
- Pass JSX as arguments (we'll see this with props in Part 3)
- Put JSX in arrays, ternaries, and any other JavaScript structure
What's Next?
In this article, we covered:
- ✔ What JSX is and how it compiles to
createElement - ✔ JSX rules (single root, close tags, className, camelCase)
- ✔ How to embed JavaScript expressions with
{} - ✔ Building and nesting components
- ✔ Rendering lists with
.map()and thekeyprop - ✔ Inline styles in JSX
In Part 3: Props, we'll learn how to pass data between components — from parent to child — using props. This is how React components communicate and become truly reusable.
Challenge: Before moving on, try modifying the profile card example. Add a "bio" field to the user object and display it. Or add a "Follow" button that toggles between "Follow" and "Following" (hint: you'll need React.useState from Part 1).
Happy coding!






