At some point, when building a React component, you'll run into a situation where you need to apply a class based on some condition. Perhaps, you need to make an image bigger based on some state, or you need to make the image round instead of square based on a prop, or you want to truncate some text based on a user’s action. You can do all of that with CSS, which means that you can conditionally apply class names to achieve this.
For example, you might have a Banner
component that has the prop active
. If you want to style the banner differently depending on that prop, what's the best way to do it? One of the best ways is to use the prop to set a different class name inside the component. Then you can write some CSS that will display the component differently when that class is applied.
There are a couple of approaches, depending on your preferences and needs. The quickest is with a ternary and another approach is to use a library. I've used both approaches, depending on the project.
Below is our banner example. It has a class of banner
, but we want to add the active
class when the active
prop is true
.
1import React from "react";
2
3const Banner = ({ children }) => <div className="banner">{children}</div>;
4
5export default Banner;
The simplest approach is to use a ternary statement inside of a template literal.
1import React from "react";
2
3const Banner = ({ active, children }) => (
4 <div className={`banner ${active ? "active" : ""}`}>{children}</div>
5);
6
7export default Banner;
In this example, banner
is always on the div
, but active
depends on the active
prop.
If you have a lot of class names that need to be conditional on the same element, it can get a little messy, but it still works.
1import React from "react";
2
3const Banner = ({ active, children }) => (
4 <div
5 className={`banner large ${active ? "active" : ""} ${
6 disabled ? "disabled" : ""
7 }`}
8 >
9 {children}
10 </div>
11);
12
13export default Banner;
In this example, banner
and large
are always on the div
, but active
depends on the active
prop, and disabled
depends on the disabled
prop.
If you find yourself doing this often, or if you use several classes conditionally on the same element, you might find it useful to use a simple JavaScript library for conditionally applying classnames together. The library is called Classnames and it's a plain JavaScript library, so it works great with React and also other JavaScript frameworks.
To use it, just install it with yarn add classnames
or npm install classnames
. Then you can import it and you can use it in your component like this:
1import React from "react";
2import classNames from "classnames";
3
4const Banner = ({ active, children, disabled }) => (
5 <div
6 className={classNames({
7 banner: true,
8 large: true,
9 active: active,
10 disabled: disabled
11 })}
12 >
13 {children}
14 </div>
15);
16
17export default Banner;
If you have classes that you always want to be included, you can set them to true
, like the example above, or you can just pass them as string arguments to classNames
like this:
1import React from "react";
2import classNames from "classnames";
3
4const Banner = ({ active, disabled }) => (
5 <div
6 className={classNames("banner", "large", {
7 active: active,
8 disabled: disabled
9 })}
10 >
11 {children}
12 </div>
13);
14
15export default Banner;
Also, if classNames
seems too long for you, remember that you can import it with any name you like. One name I've seen used quite a bit is cx
. So you could import it like this:
1import cx from 'classnames';
There is so much you can do with this! Not only can you use props to conditionally apply class names, but you can also use state and other derived values. Have fun having classes automatically added and removed using JavaScript in your React components.
And, if you're interested in using Classnames, be sure and check out the documentation on GitHub: GitHub - JedWatson/classnames: A simple javascript utility for conditionally joining classNames together.
Explore these React courses from Pluralsight to continue learning!