# JSX basics

JSX (JavaScript XML) is **a syntax extension for JavaScript used with libraries like** [React](https://react.dev/) **to describe what the user interface should look like**. It allows developers to write HTML-like markup directly within JavaScript code, making the code more readable and intuitive.

JavaScript paired with HTML enables powerful, high-level functionality with relatively simple code think dynamic updates, event handling, and interactivity without needing heavy frameworks.

**Core Concepts**

* **HTML-like Syntax:** JSX looks very similar to standard HTML, using tags and attributes.
    
* **Not Native JavaScript:** Browsers cannot read JSX directly. A tool called [**<mark>Babel</mark>**](https://babeljs.io/) transpiles (converts) JSX code into regular JavaScript function calls (specifically `React.createElement()`) before the code runs in the browser.
    
* **Represents Objects:** After compilation, a JSX expression becomes a regular JavaScript object, which React uses to build and update the Document Object Model (DOM) efficiently.
    
* **Embedding Expressions:** You can embed any valid JavaScript expression (variables, functions, calculations) inside JSX by wrapping it in curly braces `{}`.
    

---

**Example**

Source - [https://github.com/Dun-sin/Whisper/blob/main/client/src/components/NavBar.jsx](https://github.com/Dun-sin/Whisper/blob/main/client/src/components/NavBar.jsx)

As we can observe below, Using JavaScript functions with HTML making it easier to make high level functionality without complex code.

```javascript
import { useMemo } from 'react';
import { NavLink, useLocation } from 'react-router-dom';

import { Tooltip, Whisper } from 'rsuite';
import { Icon } from '@iconify/react';
import { useKindeAuth } from '@kinde-oss/kinde-auth-react';

// Store
import { useDialog } from 'src/context/DialogContext';
import { useAuth } from 'context/AuthContext';
import { socket } from 'src/lib/socketConnection';

// Lib
import { useApp } from 'src/context/AppContext';
import { NEW_EVENT_LOGOUT } from '../../../constants.json';

const linkStyle = `h-full w-full flex items-center justify-center hover:bg-primary rounded-[15px] md:max-h-[60px] md:h-[60px] md:min-h-[60px] `;
const activeStyle = linkStyle + 'bg-primary';

const NavBar = () => {
	const { authState, dispatchAuth } = useAuth();
	const { logout } = useKindeAuth();

	const { app } = useApp();
	const location = useLocation();
	const { setDialog } = useDialog();

	function logOut() {
		dispatchAuth({
			type: 'LOGOUT',
		});
		setDialog({ isOpen: false });
		logout();
	}

	const handleLogout = () => {
		setDialog({
			isOpen: true,
			text: 'Are you sure you want to logout?',
			noBtnText: 'Cancel',
			yesBtnText: 'Yes, log me out',
			handler: () => {
				if (socket.disconnected) {
					socket.volatile.emit(NEW_EVENT_LOGOUT, {
						email: authState.email,
						loginId: authState.loginId,
					});
				} else {
					socket.emit(NEW_EVENT_LOGOUT, {
						email: authState.email,
						loginId: authState.loginId,
					});
				}
				logOut();
			},
		});
	};

	const getLinkStyle = ({ isActive }) => (isActive ? activeStyle : linkStyle);
	const fullscreenPages = ['/founduser'];

	const hideNavbar = useMemo(
		() => fullscreenPages.includes(location.pathname) && app.currentChatId,
		[location, app]
	);

	return (
		<div
			className={`${
				hideNavbar && 'hidden'
			} bg-secondary md:w-[120px] md:min-h-screen md:max-h-screen items-center md:flex-col flex-row justify-between shadow-[rgb(0,_0,_0)_12px_0px_18px_-18px] p-2 md:p-5 sticky bottom-0 md:flex max-h-[70px] h-[70px] min-h-[70px]`}
		>
			<div className="hidden md:flex">
				<img src="favicon.ico" />
			</div>
			<div className="justify-between md:justify-center flex items-center md:flex-col flex-row w-full h-full gap-2 flex-nowrap overflow-auto">
				<Whisper
					placement="auto"
					controlId="control-id-hover"
					trigger="hover"
					speaker={<Tooltip>Search for random buddies</Tooltip>}
				>
					<NavLink to="/" className={getLinkStyle}>
						<Icon icon="fluent:people-search-20-regular" color="white" height="24" width="24" />
					</NavLink>
				</Whisper>
				<Whisper
					placement="auto"
					controlId="control-id-hover"
					trigger="hover"
					speaker={<Tooltip>Friends</Tooltip>}
				>
					<NavLink to="/friends" className={getLinkStyle}>
						<Icon color="white" icon="la:user-friends" height="24" width="24" />
					</NavLink>
				</Whisper>
				<Whisper
					placement="auto"
					controlId="control-id-hover"
					trigger="hover"
					speaker={<Tooltip>My Profile</Tooltip>}
				>
					<NavLink to="/profile" className={getLinkStyle}>
						<Icon icon="fluent:person-circle-20-regular" color="white" height="24" width="24" />
					</NavLink>
				</Whisper>

				{/* show only on mobile screen */}
				<div className="flex w-full md:hidden h-full">
					<Whisper
						placement="auto"
						controlId="control-id-hover"
						trigger="hover"
						speaker={<Tooltip>Settings</Tooltip>}
					>
						<NavLink to="/settings" className={getLinkStyle}>
							<Icon icon="ic:outline-settings" color="white" height="24" width="24" />
						</NavLink>
					</Whisper>
				</div>

				<div className="flex w-full md:hidden h-full">
					<Whisper
						placement="auto"
						controlId="control-id-hover"
						trigger="hover"
						speaker={<Tooltip>Logout</Tooltip>}
					>
						<button className={linkStyle} onClick={() => handleLogout()}>
							<Icon icon="majesticons:logout-half-circle" color="white" height={24} width={24} />
						</button>
					</Whisper>
				</div>
			</div>
			<div className="hidden md:flex w-full flex-col gap-2">
				<Whisper
					placement="auto"
					controlId="control-id-hover"
					trigger="hover"
					speaker={<Tooltip>Settings</Tooltip>}
				>
					<NavLink to="/settings" className={getLinkStyle}>
						<Icon icon="ic:outline-settings" color="white" height="24" width="24" />
					</NavLink>
				</Whisper>
				<Whisper
					placement="auto"
					controlId="control-id-hover"
					trigger="hover"
					speaker={<Tooltip>Logout</Tooltip>}
				>
					<button className={linkStyle} onClick={() => handleLogout()}>
						<Icon icon="majesticons:logout-half-circle" color="white" height={24} width={24} />
					</button>
				</Whisper>
			</div>
		</div>
	);
};

export default NavBar;
```

**JSX Usage in NavBar: Key Points**

1. **Conditional Rendering with Dynamic Classes**: Uses template literals for complex Tailwind class (or any class) computation: `${hideNavbar && 'hidden'}`. If hideNavbar is true then `hidden` class will be applied.
    
2. **Reusable Function Components**: `getLinkStyle({ isActive })` extracts logic for `NavLink` styling, applied consistently across 5+ navigation items.
    
3. JSX self-closing tags like `<Icon icon="fluent:people-search-20-regular" color="white" height="24" width="24" />`.
    
4. **JSX-in-JSX Nesting**: Deeply nested structure with `Whisper > NavLink > Icon` for tooltips + routing + icons. Inline handlers `onClick={() => handleLogout()}` keep JSX declarative while functions handle side effects.
    

**JSX Power**: ~80% JSX, 20% JS logic—maximum declarative UI (meaning you just say what the UI should look like, not how to build or update it step by step which is imperative) with minimal imperative code.

---

**Key Rules and Syntax Differences from HTML**

While similar to HTML, JSX has specific rules:

* **Single Root Element:** A component must return a single top-level element. To return multiple elements, you must wrap them in a single parent tag, such as a `<div>` or a `<>...</>` (a Fragment).
    
* **Close All Tags:** All tags, including self-closing elements like `<img>` or `<input>`, must be explicitly closed with a forward slash (e.g., `<img />`, `<br />`).
    
* **camelCase Attributes:** HTML attributes are written in `camelCase` in JSX because some words like `class` and `for` are reserved keywords in JavaScript.
    
    This is important to differentiate between JavaScript reserved keywords and HTML keywords, as they can conflict. For example, 'class' is used to create a JavaScript class, but it can also be used in HTML to apply styles.
    
    * `class` becomes `className`.
        
    * `for` becomes `htmlFor`.
        
* **Inline Styles:** Inline styles are specified using a JavaScript object rather than a string.
    
* **Conditional Rendering and Lists:** You can use JavaScript logic like `if` statements or the `.map()` method to conditionally render elements or lists of items directly within your JSX. (This is widely used)
    

**Why Use JSX?**

* **Improved Readability:** It makes UI code visually intuitive and easier to read and understand.
    
* **Better Developer Experience:** JSX provides more detailed error messages and warnings during development compared to writing vanilla JavaScript with `React.createElement()` calls.
    
* **Prevents XSS:** By default, React DOM escapes any values embedded within curly braces before rendering them, which helps prevent Cross-Site Scripting (XSS) attacks.
    

Note:

JSX and React are two separate things. They’re often used together, but you can [use them independently](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#whats-a-jsx-transform) [of each other. JSX is](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#whats-a-jsx-transform) a syntax extension, while React is a JavaScript library.

TSX popular now a day, every thing is same just use [TypeScript](https://www.typescriptlang.org/) instead of JavaScript.
