Difficulty: Beginner
JSX expressions are the bridge between your JavaScript logic and your rendered UI. Anything inside curly braces `{}` in JSX is evaluated as a JavaScript expression. This means you can embed variables, call functions, perform arithmetic, use ternary operators, and leverage any JavaScript expression that produces a value. This is what makes React's JSX so powerful compared to template languages with limited expression support.
Conditional expressions in JSX are used heavily in React. Since you cannot use if/else statements directly inside JSX (they are statements, not expressions), you use alternatives. The ternary operator `condition ? trueValue : falseValue` is the most common for toggling between two outputs. The logical AND `&&` operator is used when you want to render something or nothing: `{isLoggedIn && <Dashboard />}` renders Dashboard only when isLoggedIn is true. The logical OR `||` operator can provide fallbacks: `{username || 'Guest'}` shows the username or 'Guest' if it is falsy.
Template patterns in JSX refer to common ways of structuring dynamic content. One pattern is mapping arrays to elements: `{items.map(item => <li key={item.id}>{item.name}</li>)}`. Another is using immediately invoked function expressions (IIFEs) for complex logic: `{(() => { if (a) return 'X'; return 'Y'; })()}`. However, IIFEs should be avoided in favor of extracting logic into helper functions or variables defined before the return statement.
Dynamic attributes are another powerful use of JSX expressions. You can compute className, style, disabled, or any attribute dynamically: `<button className={isActive ? 'active' : 'inactive'} disabled={isLoading}>`. Spread syntax works with JSX too: `<Component {...props} />` passes all properties of the props object as individual attributes. This is useful for forwarding props or creating wrapper components.
There are some values that JSX handles specially. Booleans (`true`, `false`), `null`, and `undefined` are valid children but render nothing. This is what makes `{condition && <Element />}` work - when condition is false, JSX renders `false`, which shows nothing. However, be careful with falsy values like `0` - `{count && <List />}` will render `0` on screen when count is zero, because 0 is a falsy value that JSX does render. Always use explicit comparisons: `{count > 0 && <List />}`.
const user = { name: 'Alice', role: 'admin', loginCount: 42 };
// Variables
console.log('Name: ' + user.name);
// Function calls
console.log('Upper: ' + user.name.toUpperCase());
// Arithmetic
console.log('Next login: #' + (user.loginCount + 1));
// Template literals (also expressions)
console.log(`${user.name} is a${user.role === 'admin' ? 'n admin' : ' user'}`);
Any JavaScript expression can go inside JSX curly braces - variables, function calls, arithmetic, template literals, and more.
// Ternary operator: condition ? ifTrue : ifFalse
const isLoggedIn = true;
const greeting = isLoggedIn ? 'Welcome back!' : 'Please sign in';
console.log(greeting);
// Logical AND: renders right side only if left is truthy
const hasNotifications = true;
const notifCount = 5;
const notifText = hasNotifications && (notifCount + ' new notifications');
console.log(notifText);
// Logical OR: provides fallback for falsy values
const username = '';
const displayName = username || 'Guest';
console.log('Hello, ' + displayName);
// PITFALL: 0 is falsy but renders in JSX!
const count = 0;
const badResult = count && 'has items'; // renders 0!
const goodResult = count > 0 && 'has items'; // renders false (nothing)
console.log('Bad: ' + badResult);
console.log('Good: ' + goodResult);
Use ternary for two-way conditions, && for show-or-nothing, and || for fallbacks. Be careful with 0 and empty strings as they render visibly.
// Dynamic class names
const isActive = true;
const btnClass = isActive ? 'btn btn-active' : 'btn';
console.log('className: ' + btnClass);
// Dynamic styles
const theme = 'dark';
const bgColor = theme === 'dark' ? '#333' : '#fff';
const textColor = theme === 'dark' ? '#fff' : '#333';
console.log('bg: ' + bgColor + ', text: ' + textColor);
// Spread operator with props
const baseProps = { type: 'button', disabled: false, className: 'btn' };
const extraProps = { disabled: true, 'aria-label': 'Submit' };
const merged = { ...baseProps, ...extraProps };
console.log('disabled: ' + merged.disabled);
console.log('aria-label: ' + merged['aria-label']);
console.log('className: ' + merged.className);
Attributes can be computed dynamically using expressions. Spread syntax merges props objects, with later properties overriding earlier ones.
JSX expressions, conditional expressions, template patterns, dynamic attributes, expression limitations