Lately, I've been pondering the most effective way to apply a CSS class conditionally in React JS. While I have come across some suggestions on this topic, they seem scarce or not as detailed as I had hoped for.
Lately, I've been pondering the most effective way to apply a CSS class conditionally in React JS. While I have come across some suggestions on this topic, they seem scarce or not as detailed as I had hoped for.
To conditionally apply a class based on state, you can use the following syntax:
<div className={ this.state.condition ? 'yourClass' : '' }>
text
</div>
If you need to toggle classes based on a state variable, you can do it like this:
<div className={ this.state.toggle ? 'active' : 'inactive' }>
text
</div>
The React documentation provides guidance on manipulating class names and recommends using the classnames
NPM package.
The documentation for this package is extremely helpful.
A snippet directly from the package's README
: Usage section
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: false, bar: true }); // => 'bar'
// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true });
// => 'foo bar baz quux'
// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, '');
// => 'bar 1'
Most responses assume the topic revolves around conditionally toggling CSS classes using a ternary if statement, but it becomes more complicated when you want to include class names as options. Using multiple ternary ifs with empty false expressions can be quite verbose. Resorting to an NPM package might be excessive, while creating a function could also be seen as overkill by some.
My approach is different.
const classNames = [
"className1",
condition1 && "className2",
condition2 && "className3",
condition3 && "className4",
].filter(e => e).join(" ");
Update as of June 2021
I've noticed that this response still receives sporadic upvotes. To provide a more current example, here's a revised snippet utilizing a concise arrow function:
const cls = (...classes) => classes.filter(Boolean).join(' ');
<div className={cls('mandatoryClass', condition && 'optionalClass')} />
If you find yourself needing to add a conditional class to an existing one, here's a helpful tip
<span className={'fa ' + (this.state.dropdownActive ? 'fa-angle-up' : 'fa-angle-down')}></span>
In this scenario, I am demonstrating how to display an arrow icon for a dropdown based on the dropdown's state. The class fa
must remain constant to apply the font-family to the span, with only the need to alternate between fa-angle-up
and fa-angle-down
.
Here's the same example using template literals
<span className={`fa ${this.state.dropdownActive ? 'fa-angle-up' : 'fa-angle-down'}`}></span>
For an easy way to manage CSS class names in your React components, consider using the Classnames library created by Jed Watson. You can find more information on this library at https://github.com/JedWatson/classnames
With the classNames function provided by this library, you can pass a string or object as arguments. If a key's value is falsy, it will not be included in the final output.
var classNames = require('classnames');
var Button = React.createClass({
// ...
render () {
var btnClass = classNames({
'btn': true,
'btn-pressed': false,
'btn-over': true
});
// The output will be: btnClass = "btn btn-over"
return <button className={btnClass}>{this.props.label}</button>;
}
});
If you have any questions after reviewing the documentation, feel free to reach out!
Cheers
The solution provided by another author in the comment above worked perfectly for my situation.
<div className={ this.state.end ? 'hidden' : 'shown' }>text</div>
Additionally, you can add more classes by simply separating them with a space.
Personally, I believe the solutions provided by the classnames
library are the most accurate. However, if you prefer not to add another dependency, you can create your own simple implementation that functions similarly to jQuery:
function getClassBuilder () {
return {
array: [],
add: function (className) {
if (this.array.indexOf(className) < 0) {
this.array.push(className);
}
},
remove: function (className) {
var index = this.array.indexOf(className);
if (index > -1) {
this.array.splice(index, 1);
}
},
toString: function () {
return this.array.join(' ');
}
}
}
Then, when you need to utilize it:
var builder = getClassBuilder();
builder.add('class1');
builder.add('class2');
if (condition) { builder.remove('class1') };
<a href="#" className={builder.toString()}>Button</a>
Conditional Styling with Class Names
<div className={"wrapper " + (this.props.active === true ? 'active' : 'inactive')}>
Multiple Conditions for Dynamic Styling
<div className={"box " + (this.props.condition === true ? 'show ' : 'hide ') + (this.props.secondCondition === true ? 'visible' : 'hidden')}>
Make sure to leave space between conditional classes and static classes at the end
This small package (around 220 bytes) has been a game-changer for me when it comes to reducing boilerplate code: Check out clsx on npm
With just a few lines of code, you can achieve the same result:
import clsx from 'clsx';
<div className={clsx('my-class', <some dynamic optional classes>)}>
or
<div className={clsx('class1', true && 'class2', 'class3')}>
//=> 'class1 class2 class3'
After some experimentation, I've discovered that incorporating in-line styles in React JS is actually quite achievable and not as daunting as initially perceived. This information could be beneficial for individuals embarking on their journey with React JS.
I have identified two methods and purposes for including in-line styles:
(1) Embedding a class name within a style attribute as an object allows for styling within a regular CSS stylesheet, directly inside a JSX file, or for conditional CSS usage
EXAMPLE 1
const classNameAsAPlainObject = {
color: '#333333',
backgroundColor: '#999999'
}
<a href="#" className="an-existing-class" style={classNameAsAPlainObject} >
Button
</a>
EXAMPLE 2
const conditionIsSomething = {
color: 'red'
}
<a href="#" className="an-existing-class" style={conditionIsSomething ? 'classNameBasedOnCondition' : ' ' }>
Button
</a>
The second example illustrates the declaration of two different classes based on desired outcomes, or one class depending on whether a condition is met or none if it isn't.
(2) Incorporating a class name into the regular className attribute is necessary when a condition is required, ensuring that existing class names are taken into account. It's important to note that this method necessitates styling in a standard CSS file. If no condition is needed, simply add the class normally to the className attribute.
EXAMPLE 3
<a href="#" className={"an-existing-class " + (conditionIsSomething ? 'thisClass' : 'thatClass')}>
Button
</a>
EXAMPLE 4
<a href="#" className={"an-existing-class " + (conditionIsSomething ? 'aClassIsAdded' : ' ')}>
Button
</a>
Once again, depending on the condition, either one class can be declared or none as exemplified in example 4. Ensure to include a space after "an-existing-class" before the closing quote to allow room for the conditional class.
To summarize, when adding a class and styling as an object (as shown in Example 1 and 2), you can customize it within the JSX file. However, when adding a class name to the "className" attribute, styling will need to be done in a regular CSS file. Although I haven't personally tested this, I am eager to do so. Should anyone have alternative insights, please share them with me.
In the index.js file, I have initialized socket.io and need to pass the socket object to the route module. const express = require('express'); const app = express(); var bodyParser = require('body-parser'); var mongoose = require(&apos ...
I am currently working on a unique feature where users can click on the left navigation link and the right section will automatically scroll to the corresponding box. For instance, if a user clicks on the second link in the navigation, the right-side div ...
I am looking to create a customizable Header component with different sets of buttons that trigger various functions. For example, on the home page, the buttons could be "visit about page" and "trigger vuex action A", while on the about page they could be ...
I currently have two jQueryUI datepickers integrated into my webpage. The initialization code for both is as follows: jQuery("#departureDate").datepicker({ beforeShow: function() { getDatesForCalendar("outbound"); }, numberOfMonths: 3 ...
In order to extract a list of distinct groups from a list of users, where each user is affiliated with one or more groups at various levels governed by a hierarchy, the hierarchy needs to be reflected in the group as an address similar to an IP address. It ...
What is the best way to create a non-blocking sleep function in JavaScript or jQuery? ...
After implementing the script, I noticed a strange behavior. When I click it on load, everything works perfectly. However, when I click it via a dynamically created element, the HTML seems to shift or stretch on the first click before returning to normal. ...
Having an issue passing a value from a Material-UI Button to its click handler. The value is always showing as undefined. I used to get the value when using a simple button, but not anymore. const categoryChangedHandler = (e) => { console.log("c ...
Struggling with sending a "large" table using OfficeJS: functionfile.html loaded from manifest route <script> (function (){ "use strict"; Office.initialize = function (reason) { $(document).ready(function() { $("#send-data-button").cli ...
I have a boolean state called bgWhite. When it changes, the background color changes accordingly. This setup is located in the index.js file within the pages directory. Is there a way for me to access the bgWhite state from another component in order to m ...
In short: I am developing a node application that sends requests using the secure version of HTTP, which is HTTPS. When I incorrectly configure my request options, I encounter the following error: Node.js Hostname/IP doesn't match certificate' ...
I've been tackling the alignment of elements in my menu header, but for some reason, they're not lining up horizontally as intended. Instead, they are stacked below each other. Here's the link to my jsfiddle Here's a snippet of my HTML ...
I have a domain at example.com/index.html and I'm looking to create a .txt file within the domain called examples.com/file.txt that will store the HTML content below when clicking on the save button: .js: $('.saveButton').on('click&ap ...
For a school project, I am creating a small website that sells hip hop beats using Vue.js. One of the pages I'm working on allows users to preview a beat and make a purchase. To enable beat previews, I have included an HTML audio tag. The data for eac ...
I have a grid panel created with ExtJS that contains over 20 rows of data. My goal is to use WebdriverIO as the test driver to search through each row for an icon indicating active mode. How can I write a script that searches each row until it finds the f ...
Can I customize the configuration for my ng build --watch command in order to efficiently bundle and minify files on disk each time a modification is made? ...
I currently have a get method in my Express app that renders data from a MongoDB collection called "Members" on the URL "/agileApp". This is working fine, but I now also want to render another collection called "Tasks" on the same URL. Is it possible to ...
Is it possible to create a JSON file from a model built with Three.js in Webgl, similar to exporting a JSON model from Blender and loading it with THREE.JSONLoader().load? I would like to know if anyone has experience or information on this. ...
Having some trouble calling a PHP method from JavaScript to query a database and use the results in my JS functionality. Currently, the console.log(output) in my ajax call is only displaying: string '{"action":"getResults"}' (length=23) I&apo ...
I have been using React-bootstrap to style my buttons, however, I am facing difficulty in overriding the default btn and btn-danger classes provided by Bootstrap. Is there a way for my custom class slotTiming-box-button to take precedence over the btn and ...