frontend
React ClassNames Aggregator
January 24, 2026
React ClassNames Aggregator
Overview
The classNames utility is a popular helper function for conditionally joining classNames together. It's commonly used in React applications to dynamically construct className strings based on conditions, making it easier to apply conditional styling.
Basic Implementation
// Create a classNames util/polyfill method
/**
* @param {...(any|Object|Array<any|Object|Array>)} args
* @return {string}
*/
export default function classNames(...args) {
const classes = [];
const process = (arg) => {
if (!arg) return;
if (typeof arg === "string" || typeof arg === "number") {
classes.push(arg);
} else if (Array.isArray(arg)) {
arg.forEach(process); // Recurse into arrays
} else if (typeof arg === "object") {
for (let key in arg) {
if (Object.hasOwn(arg, key) && arg[key]) {
classes.push(key);
}
}
}
};
args.forEach(process);
return classes.join(" ");
}
Usage Examples
Basic Usage
classNames('foo', 'bar'); // 'foo bar'
classNames('foo', { bar: true }); // 'foo bar'
classNames({ 'foo-bar': true }); // 'foo-bar'
classNames({ 'foo-bar': false }); // ''
classNames({ foo: true }, { bar: true }); // 'foo bar'
classNames({ foo: true, bar: false }); // 'foo'
Conditional Classes
classNames('foo', { bar: isBar }, { baz: isBaz });
Arrays
classNames(['foo', 'bar']); // 'foo bar'
classNames(['foo', { bar: true }]); // 'foo bar'
React Example
function Button({ primary, disabled, className, children }) {
return (
<button
className={classNames(
'btn',
{
'btn-primary': primary,
'btn-disabled': disabled
},
className
)}
>
{children}
</button>
);
}
Best Practices
- Use for Conditional Classes: Perfect for conditional styling
- Keep It Simple: Don't overcomplicate logic
- Performance: Efficient for most use cases
- Type Safety: Consider TypeScript for type safety