Conditional Class Rendering in React using CLSX
Anton Martyniuk
Posted on May 20, 2024
Originally published at https://antondevtips.com.
When developing React applications, managing conditional class names can quickly become cumbersome, especially as components grow in complexity.
Traditionally, developers concatenate strings and use conditional logic to handle these cases, which can lead to error-prone and hard-to-read code.
In this blog post, we'll explore how the clsx library offers a cleaner, more efficient solution to this common problem, providing examples to demonstrate its advantages.
How to Conditionally Apply CSS Classes - Manual Approach
We are going to explore a Button
React component that has a single prop that indicates whether the button is active.
The traditional method of appending classes conditionally in React is achieved by manually writing classes concatenations:
const Button = ({ isActive, children }) => {
let buttonClass = "btn";
if (isActive) {
buttonClass += " btn-active";
}
return <button className={buttonClass}>{children}</button>;
}
When a button needs to be active - a btn-active
css class is applied that make changes to the button's background color.
Let's define 2 buttons and see how they differ:
<div>
<Button isActive={false}>
Register
</Button>
<Button isActive={true}>
Subscribe
</Button>
</div>
Now let's explore a more complex Button
component that have several states like primary, danger, or disabled:
const ComplexButton = ({ primary, danger, disabled, children }) => {
let buttonClass = "btn";
if (primary) {
buttonClass += " btn-primary";
}
if (danger) {
buttonClass += " btn-danger";
}
if (disabled) {
buttonClass += " btn-disabled";
}
return (
<button className={buttonClass}>
{children}
</button>
);
}
Let me explain what we are doing here:
we start with a base class btn
and append additional classes based on whether the button is primary, danger or disabled.
This modifies the styling to show different borders and background colors for the button.
Primary button - is a main button on the current screen and should be visually distinguished from other buttons, for example a save button.
Danger button - is a button that indicates a possible risky action, like rejecting the updated data.
As you can see, even for moderately complex conditions, the class string handling becomes verbose and harder to read.
And we need so much code to write.
Manual string concatenation is susceptible to errors, such as missing spaces between class names or misplacing condition checks.
As more conditions are added, the approach becomes difficult to maintain.
How to Conditionally Apply CSS Classes - Using CLSX Library
In such use cases clsx library comes to the rescue.
clsx is a tiny library designed to make conditional class rendering in React (and beyond) much simpler and more readable.
It allows you to write expressions that are easier to maintain and understand.
Here's how you can refactor the first example of a Button
component using clsx library:
import clsx from 'clsx';
const Button = ({ isActive }) => {
return <button className={clsx("btn", { "btn-active": isActive })}>Register</button>;
}
clsx accepts multiple arguments and merges them intelligently. Arguments can be strings, objects, or arrays, providing great flexibility.
With a help of clsx library you can have a pretty simple and easy to read code even for a complex Button
component:
import clsx from 'clsx';
const ComplexButton = ({ primary, danger, disabled, children }) => {
return (
<button
className={clsx("btn", {
"btn-primary": primary,
"btn-danger": danger,
"btn-disabled": disabled
})}
>
{children}
</button>
);
}
More Examples of Using CLSX Library
We'll build a UserProfile
component that displays different styles based on the user's status, such as whether they are online, whether their subscription is active and what role they have.
First, let's write this manually:
const UserProfile = ({ user }) => {
let avatarClass = "avatar";
let nameClass = "username";
if (user.isOnline) {
avatarClass += " avatar-online";
}
if (user.role === "admin") {
avatarClass += " avatar-admin";
} else if (user.role === "moderator") {
avatarClass += " avatar-moderator";
}
if (user.isSubscriber) {
nameClass += " username-highlighted";
}
return (
<div className="user-profile">
<h1 className={nameClass}>{user.name}</h1>
<ProfileIcon className={avatarClass} />
</div>
);
}
Let me explain what we are doing here:
- We start with a base class
avatar
and append additional classes based on whether the user is online or what role he has. This modifies the styling to show different borders and colors for the avatar. - The base class for the user's name is
username
, and if the user is a subscriber, we add a highlighted style to make it stand out.
Let's show a few users:
<div>
<UserProfile name={"Anton"} isSubscriber={true} role={"admin"} isOnline={true} />
<UserProfile name={"John"} isSubscriber={true} role={"moderator"} isOnline={true} />
<UserProfile name={"Nick"} isSubscriber={true} role={""} isOnline={false} />
<UserProfile name={"Tim"} isSubscriber={false} role={""} isOnline={false} />
</div>
And here is a much better version when using clsx library:
import clsx from "clsx";
const UserProfile = ({ user }) => {
const avatarClasses = clsx("avatar", {
"avatar-online": user.isOnline,
"avatar-admin": user.role === "admin",
"avatar-moderator": user.role === "moderator"
});
const nameClasses = clsx("username", {
"username-highlighted": user.isSubscriber
});
return (
<div className="user-profile">
<h1 className={nameClasses}>{user.name}</h1>
<ProfileIcon className={avatarClasses} />
</div>
);
}
Nuances When Using CLSX Library
- The clsx function can take any number of arguments, that can be either: string, boolean, array or object.
- Any
false
type of values are discarded, for example:
// This returns empty string ""
clsx(true, false, 0, "", null, undefined, NaN);
- There are 2 versions of clsx library: original (239 bytes) and lite (140 bytes). The lite has the same API as original but accepts only string arguments.
Summary
clsx library offers a more elegant solution for handling conditional class names in React, enhancing code readability and maintainability.
It allows developers to more easily manage multiple conditional classes without the boilerplate of manual string concatenation, clsx makes your React components cleaner and less prone to bugs.
Hope you find this blog post useful. Happy coding!
Originally published at https://antondevtips.com.
After reading the post consider the following:
- Subscribe to receive newsletters with the latest blog posts
- Download the source code for this post from my github (available for my sponsors on BuyMeACoffee and Patreon)
If you like my contentβββ consider supporting me
Unlock exclusive access to the source code from the blog posts by joining my Patreon and Buy Me A Coffee communities!
Posted on May 20, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.