104

I am trying to understand some uses of clsx in assigning classnames to a component in React.

The construct

className={clsx(classes.menuButton, open && classes.hide)} 

is clear enough. It applies classes.menuButton, and also applies classes.hide if the value of the boolean open is true.

My question relates to this second example:

className={clsx(classes.appBar, {[classes.appBarShift]: open })}

This will apply classes.appBar. But what is the meaning of the second parameter?

Dupocas
  • 20,285
  • 6
  • 38
  • 56
millport
  • 2,411
  • 5
  • 23
  • 19

3 Answers3

153

clsx is generally used to conditionally apply a given className

This syntax means that some class will only be applied if a given condition evaluates to true

const menuStyle = clsx({
    [classes.root] : true, //always applies
    [classes.menuOpen] : open //only when open === true
})

In this example [classes.menuOpen] (which will evaluate to something like randomclassName123) will only be applied if open === true


clsx basically outputs a string interpolation. So you don't have to necessarily use it.

There are many supported syntax that you can check in the official docs

Instead of

<div className={`${classes.foo} ${classes.bar} ${classes.baz}`} />

You can use it like this

const { foo, bar, baz } = classes
const style = clsx(foo, bar, baz)

return <div className={style} />
Dupocas
  • 20,285
  • 6
  • 38
  • 56
  • 10
    Thanks. If I understand you correctly then 'open && classes.menuOpen' has exactly the same effect as '[classes.menuOpen] : open'. – millport Aug 19 '19 at 14:06
  • Yeap. They are just two different ways to achieve the same result – Dupocas Aug 19 '19 at 14:07
  • 1
    Thanks again. Last comment - The construct 'className={clsx(classes.appBar, {[classes.appBarShift]: open })}' would have the same effect as 'className={clsx(classes.appBar, {classes.appBarShift: open})}'. The array is really only needed when there is more than one rule dependent on the value of open. – millport Aug 19 '19 at 14:21
  • 2
    Yes. You can check all the possible sintaxes for `clsx` [here](https://www.npmjs.com/package/clsx) – Dupocas Aug 19 '19 at 15:37
  • No... the array syntax is for dynamic keys: https://stackoverflow.com/a/19837961/3494249 `{classes.appBarShift: open}` would cause an error; `{[classes.appBarShift]: open}` would create an object with the value of `classes.appBarShift` as a key. – goldins Nov 20 '19 at 14:27
  • He is refering to pass an array of classes to `clsx`. Dynamic keys don't have anything to do with that. Yes his example code will fail for the lack of `[]` delimiting the key. But that wasn't his question – Dupocas Nov 20 '19 at 14:30
30

Many people already explained it pretty well. I still wanted to add an example containing className. In the example you can see different classes, applied if a given condition evaluates to true. In the example you can apply a class with a boolean value, a boolean variable or a compared string (If match, return true). The class classes.drawer is always applied and does not depend on a condition.

className={clsx(classes.drawer, {                  // classes.drawer is applied always
          [classes.drawerOpen]: true,              // classes.drawerOpen is applied always, bool = true
          [classes.drawerClose]: !open,            // you can also use boolean variable
          [classes.drawerRed]: colorVar === 'red', // you can also use string variable
        })}
Amel
  • 653
  • 9
  • 15
  • 2
    Can you please add some explaination to your code? [Code-only answers may fall under 'Very Low Quality' ...and are candidates for deletion....We've always touted that we aren't a code factory. We are the people who teach others to fish. Code-only answers only feed a person for a day](http://meta.stackexchange.com/questions/148272/is-there-any-benefit-to-allowing-code-only-answers-while-blocking-code-only-ques) – dan1st Aug 29 '20 at 11:59
2

classes.appBarShift will be applied only if open evaluates to true. If the array has more classes all of them will be applied if open evaluates to true

Aditya
  • 771
  • 5
  • 11