JSX (JavaScript XML) is a syntax extension for JavaScript that allows you to write code resembling HTML directly in JavaScript. It is a declarative way of describing how the UI structure should look in React.
For a programmer who is just starting their adventure with React, JSX may seem strange - how is it possible that suddenly in the middle of JavaScript, HTML-like tags appear?
Imagine JSX as a translator between the JavaScript world and the HTML world. It allows you to describe UI structure in a way that is readable for humans (similar to HTML) while retaining all the power of JavaScript.
It's important to understand that browsers don't understand JSX natively. Before the code reaches the browser, it is compiled into regular JavaScript by tools like Babel.
For example, this JSX code:
1const element = <h1>Hello, world!</h1>;Is transformed into:
1const element = React.createElement(
2 'h1',
3 null,
4 'Hello, world!'
5);This is precisely why we always import React at the beginning of files with JSX, even if we don't use it directly -
React.createElement is used behind the scenes.JSX may look like HTML, but it has several unique features and rules worth understanding:
Unlike HTML, where attributes are written in lowercase, in JSX many attributes are written in camelCase format:
1// HTML
2<div onclick="handleClick()" tabindex="0" class="container">
3
4// JSX
5<div onClick={handleClick} tabIndex={0} className="container">Notice the differences:
onclick -> onClicktabindex -> tabIndexclass -> className (because "class" is a reserved word in JavaScript)In JSX, attribute values are not always strings. You can use any JavaScript expression by enclosing them in curly braces:
1// Numeric value
2<input maxLength={10} />
3
4// Expression
5<img src={user.avatarUrl} />
6
7// Ternary operator (conditional operator)
8<div className={isActive ? 'active' : 'inactive'}>
9
10// Function
11<button onClick={handleClick}>In JSX, tags without children must have a closing slash:
1// HTML
2<input type="text">
3
4// JSX
5<input type="text" />In HTML, some tags can remain unclosed (e.g.,
<img>, <br>), but in JSX all tags must be properly closed:1// Invalid in JSX
2<img src="logo.png">
3
4// Valid in JSX
5<img src="logo.png" />JSX requires returning only one parent element. If you want to return multiple elements, you must wrap them in a container:
1// Invalid in JSX
2function Component() {
3 return (
4 <h1>Title</h1>
5 <p>Paragraph</p>
6 );
7}
8
9// Valid in JSX
10function Component() {
11 return (
12 <div>
13 <h1>Title</h1>
14 <p>Paragraph</p>
15 </div>
16 );
17}If you don't want to introduce an additional DOM element, you can use a Fragment:
1function Component() {
2 return (
3 <>
4 <h1>Title</h1>
5 <p>Paragraph</p>
6 </>
7 );
8}You can use JavaScript expressions in JSX by placing them in curly braces
{}:1function Greeting({ user }) {
2 return (
3 <div>
4 {/* Conditional expression */}
5 {user ? <h1>Welcome, {user.name}!</h1> : <h1>Welcome, stranger!</h1>}
6
7 {/* Performing calculations */}
8 <p>Your account was created {calculateDaysAgo(user.createdAt)} days ago</p>
9
10 {/* Mapping a list */}
11 <ul>
12 {user.hobbies.map(hobby => (
13 <li key={hobby.id}>{hobby.name}</li>
14 ))}
15 </ul>
16 </div>
17 );
18}You can use the spread operator (
...) to pass all properties of an object as props:1const buttonProps = {
2 type: 'submit',
3 disabled: false,
4 className: 'primary-button'
5};
6
7<button {...buttonProps}>Submit</button>You can dynamically determine element attributes:
1const inputType = isPassword ? 'password' : 'text';
2<input type={inputType} />JSX offers several ways to conditionally render elements:
1// 1. Using the ternary operator
2{isLoggedIn ? <UserProfile /> : <LoginButton />}
3
4// 2. Using the logical && operator
5{isLoggedIn && <WelcomeMessage />}
6
7// 3. Using a variable
8let button;
9if (isLoggedIn) {
10 button = <LogoutButton />;
11} else {
12 button = <LoginButton />;
13}
14return <div>{button}</div>;In JSX, inline styles are defined as JavaScript objects:
1const divStyle = {
2 color: 'blue',
3 backgroundColor: 'lightgray',
4 padding: '10px',
5 // Note that properties with hyphens (like background-color)
6 // are written in camelCase (backgroundColor)
7};
8
9<div style={divStyle}>Styled text</div>
10
11// Or directly in JSX
12<div style={{ fontWeight: 'bold', fontSize: '16px' }}>Bold text</div>Comments in JSX are placed inside curly braces and use JavaScript comment syntax:
1<div>
2 {/* This is a comment in JSX */}
3 <h1>Title</h1>
4 {/*
5 You can also use
6 multiline comments
7 */}
8</div>JSX does not render boolean values, null, and undefined:
1// These expressions render nothing on screen
2<div>{true}</div>
3<div>{false}</div>
4<div>{null}</div>
5<div>{undefined}</div>
6
7// But numbers and strings are rendered
8<div>{0}</div>
9<div>{"string"}</div>Remember that quotes are used for string values and curly braces for JavaScript expressions:
1// Correct
2<input type="text" maxLength={10} />
3
4// Incorrect
5<input type={text} maxLength="10" /> // error: 'text' is not definedYou cannot use if/else statements directly in JSX because JSX is an expression, not a statement:
1// Incorrect
2<div>
3 {if (isLoggedIn) {
4 return <UserProfile />;
5 } else {
6 return <LoginButton />;
7 }}
8</div>
9
10// Correct - use the ternary operator
11<div>
12 {isLoggedIn ? <UserProfile /> : <LoginButton />}
13</div>JSX is one of the most important aspects of React, which greatly simplifies creating user interfaces. Thanks to JSX, you can:
Remember that JSX is just syntax that is transformed into
React.createElement() calls. Understanding the rules and capabilities of JSX is key to effective programming in React.