rotem-horovitz
    _hello_about-me_games_projects_blog
find me in:
privacy
← Back to blog

The Do’s and Don’ts of Clean, Reusable React JSX

February 27, 2025 | 3 min read
reactjsxbest-practices

🧼 The Do’s and Don’ts of Clean, Reusable React JSX

JSX is React’s bread and butter—a sweet syntax layer that makes our UI code feel intuitive and expressive. But just like butter, if you overdo it or spread it wrong, things get messy.

This guide outlines the golden rules for writing JSX that’s clean, maintainable, and pleasing to your fellow developers (and future-you at 2 AM).


✅ DO: Keep JSX Declarative and Clean

React wants to tell a story. Let it read like a story.

<Button
	onClick={handleClick}
	disabled={isLoading}
>
	{buttonLabel}
</Button>

But avoid logic gymnastics right in the middle of your JSX:

// ❌ Bad
<Button onClick={() => isValid && submitForm()}>
	{someFlag ? (otherFlag ? 'Yes' : 'Maybe') : 'No'}
</Button>

✅ Better

const buttonLabel = getButtonLabel(someFlag, otherFlag);

const handleClick = () => {
	if (isValid) {
		submitForm();
	}
};

<Button onClick={handleClick}>{buttonLabel}</Button>;

Rule of thumb: If your JSX looks like a puzzle, pull the logic out and name it something readable.


❌ DON'T: Use Ternaries in JSX (for anything)

Yes, ternaries are concise. Yes, they make you feel clever. But no, they're not readable at scale.

// ❌ Nope
<div>
	{user.isAdmin ? (user.isSuperAdmin ? 'Super Admin' : 'Admin') : 'User'}
</div>

✅ Clean it up

const roleLabel = getRoleLabel(user);

<div>{roleLabel}</div>;

Let your JSX breathe. Logic belongs in variables, hooks, or helper functions.


✅ DO: Extract Inline Functions to Constants or useCallback

Every time you define a function in JSX, React re-creates it on every render. This can break useMemo, React.memo, and your soul.

// ❌ Bad
<MyComponent onClick={() => doSomething(item.id)} />
// ✅ Better
const handleClick = () => doSomething(item.id);

<MyComponent onClick={handleClick} />;

Or if needed:

const handleClick = useCallback(() => {
	doSomething(item.id);
}, [item.id]);

It’s like inviting a friend to dinner: give them a name, don’t make them show up anonymous.


❌ DON'T: Use Magic Values in JSX

Magic values are fine in fairy tales, but not in your markup.

<header style={{ marginTop: 37 }}>Hello</header>
// ✅ Good
const HEADER_MARGIN = 37;

const headerStyle = {
	marginTop: HEADER_MARGIN,
};

<header style={headerStyle}>Hello</header>;

Named constants speak volumes. And when the design system changes? You’ll thank yourself.


✅ DO: Break Down Complex JSX into Components

If your JSX block is starting to look like it belongs in the Louvre... extract it!

// ❌ Instead of this:
items.map(item => {
	const handleBuy = () => buyItem(item.id);

	return (
		<div key={item.id}>
			<h3>{item.title}</h3>
			<p>{item.description}</p>
			<Button onClick={handleBuy}>Buy</Button>
		</div>
	);
});
// ✅ Break it down:
items.map(item => (
	<StoreItem
		key={item.id}
		item={item}
		onBuy={buyItem}
	/>
));

Cleaner code. Reusable components. Fewer bugs. Happier devs.


❌ DON'T: Nest JSX Like It’s Inception

Fragments are great. But double-nesting them, triple-nesting them, nesting <div>s like Russian dolls? Not great.

// ❌ Over-nested
<>
	<div>
		<section>
			<div>
				<ul>
					<li>
						<a href="#">Help</a>
					</li>
				</ul>
			</div>
		</section>
	</div>
</>

✅ Simplify layout. Use semantic tags. Extract structure where it gets gnarly.


✅ DO: Use Meaningful, Consistent Naming

You’re not just writing for yourself. You’re writing for Karen from QA and Dev Dave from the future.

// ❌ Confusing
<Thing stuff={value} onDo={handleIt} />

// ✅ Clear
<UserCard user={user} onEdit={handleEditUser} />

JSX is not the place for riddles. Save that for your escape room hobby.


❌ DON'T: Spread Props Blindly

// ❌ What horrors lie within this {...props}?
<MyComponent {...props} />

Instead, be explicit:

<MyComponent
	title={title}
	onClick={handleClick}
/>

Clarity > Convenience. Always.

Prop spreading is generally discouraged as it can lead to unintended behavior or make the code harder to understand. However, it is acceptable in cases where all props need to be passed down to a child component or when working with higher-order components (HOCs) or utility wrappers.


❌ DON'T: Use Duplicate or Unstable Keys

✅ DO: Use a Unique key per .map()

React uses the key prop to track items inside a list. It does not need to be globally unique — only unique within that specific .map().

// ❌ Bad – index can break if the list changes
items.map((item, index) => (
	<ListItem
		key={index}
		item={item}
	/>
));
// ✅ Good – stable and unique within this map
items.map(item => (
	<ListItem
		key={item.id}
		item={item}
	/>
));

Avoid using index unless your list is completely static and never changes. Keys should be predictable, stable, and unique within the list they belong to.


Wrap-Up: JSX Zen Mode

Here’s your JSX mantra:

  • Keep it declarative — logic before render.
  • Extract everything — ternaries, inline functions, magic numbers.
  • Name wisely — clarity beats cleverness.
  • Componentize like a boss — even small chunks.
  • Use proper keys — unique per map, stable per item.
  • Never write JSX you wouldn’t want to debug with a hangover.

React rewards the developer who shows restraint. So write JSX like it’s poetry — with purpose, clarity, and not a ternary in sight.

Comments

Sign in to leave a comment

Loading comments...