Add dynamically named nested class from SCSS to React

Viewed 21

Quick description: I have an Announcement component that receives a type prop upon its mounting. Based on the string provided in the type prop a class has to be set. The component imports a .scss module which I deconstruct in a style variable. The .scss module has nested classes and I'm unable to access the nested classes there.

Component.js

import style from '../styles/Announcement.module.scss';
...
render() {
  const { type, message } = this.props;

  return <div className={`${style.announcement} ${style[type]}`}>{message}</div>
}

Announcement.module.scss

@import 'variables';

.announcement {
  width: 100%;
  padding: 1.5rem;
  color: $announcement;
  min-height: 15rem;

  .success {
    background-color: $lightgreen;
  }
}

There exist the _variables.scss file and it is imported. The .announcement class gets applied to the <div>. The .success class doesn't get applied (even if type IS success).

I guess I could simply unnest the classes, but I want to know why it does not get applied and I want to know if there's any possibility to solve this situation without resorting to unnesting.

Thank you in advance!

1 Answers

I think the best solution in your case would be to use the package classNames or clsx.

Here is an extract from their docs

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: true }); // => 'foo bar'

Which would look like this in your code

<div 
  className={classNames(
    styles[announcement], 
    { [styles.success]: type === 'success' }
  )} 
>
  {message}
</div>

Related