【React】classNameでよく使う定義方法(複数クラス、条件付きクラス)

JavaScript

基礎知識: classNameの利用方法について

classNameにクラス名をセットすると当該CSSクラスが適用されます。

以下はbuttonタグにstyles.btnクラスを適用する例です。

src/components/shared/Button.tsx

import React, { FC } from "react";
import styles from "./Button.module.css";

type Props = {
  label: string;
  onClick: () => void;
};

export const Button: FC<Props> = ({ label, onClick }) => {
  return (
    <button className={styles.btn} onClick={onClick}>
      {label}
    </button>
  );
};

複数のクラスを付与する方法

classNameに複数のクラス名をセットする際はスペース区切りでクラス名を指定します。
クラス名を変数で管理している場合は式展開(バッククオートで囲まれた${}の中に式を記述)を利用します。

以下はbuttonタグにstyles.btnクラスとstyles.blueクラスを適用する例です。

src/components/shared/Button.tsx

import React, { FC } from "react";
import styles from "./Button.module.css";

type Props = {
  label: string;
  onClick: () => void;
};

export const Button: FC<Props> = ({ label, onClick }) => {
  return (
    <button
      className={`${styles.btn} ${styles.blue}`}
      onClick={onClick}
    >
      {label}
    </button>
  );
};

classnamesを使う場合は以下のようになります。
classnamesを利用する場合はカンマ区切りでクラス名を指定します。

src/components/shared/Button.tsx

import React, { FC } from "react";
import styles from "./Button.module.css";
+ import cx from "classnames";
(略)
    <button
-     className={`${styles.btn} ${styles.blue}`}
+     className={cx(styles.btn, styles.blue)}
      onClick={onClick}
    >
      {label}
    </button>
(略)

条件の真偽値によって付与するクラスを変える方法

条件の真偽値に応じてclassNameにセットするクラス名を変更する場合は三項演算子を利用します。

以下はPropsのsize"s"ならばbuttonタグにstyles.btnSmallクラスを、"s"以外ならばstyles.btnLargeクラスを適用する例です。

src/components/shared/Button.tsx

import React, { FC } from "react";
import styles from "./Button.module.css";

export const Size = {
  Small: "s",
  Large: "l",
} as const;

type Size = typeof Size[keyof typeof Size];

type Props = {
  label: string;
  onClick: () => void;
  size: Size;
};

export const Button: FC<Props> = ({ label, onClick, size }) => {
  return (
    <button
      className={`${size === "s" ? styles.btnSmall : styles.btnLarge}`}
      onClick={onClick}
    >
      {label}
    </button>
  );
};

classnamesを使う場合は以下のようになります。

src/components/shared/Button.tsx

import React, { FC } from "react";
import styles from "./Button.module.css";
+ import cx from "classnames";
(略)
    <button
-     className={`${size === "s" ? styles.btnSmall : styles.btnLarge}`}
+     className={cx(size === "s" ? styles.btnSmall : styles.btnLarge)}
      onClick={onClick}
    >
      {label}
    </button>
(略)

「必ず付与するクラスと、条件の真偽値に応じて付与されるクラス」が混在している場合

クラス名と三項演算子をスペース区切りで記述することにより「複数のクラス名をセット、ただし条件に応じて付与されるクラス名が変更される」という実装ができます。

以下はbuttonタグにstyles.btnクラスと、Propsのdisabledの真偽値に応じてstyles.disabledクラスもしくはstyles.activeクラスを適用する例です。

import React, { FC } from "react";
import styles from "./Button.module.css";

type Props = {
  label: string;
  onClick: () => void;
  disabled: boolean;
};

export const Button: FC<Props> = ({ label, onClick, disabled }) => {
  return (
    <button
      className={`${styles.btn} ${disabled ? styles.disabled : styles.active}`}
      onClick={onClick}
      disabled={disabled}
    >
      {label}
    </button>
  );
};

classnamesを使う場合は以下のようになります。

src/components/shared/Button.tsx

import React, { FC } from "react";
import styles from "./Button.module.css";
+ import cx from "classnames";
(略)
    <button
-     className={`${styles.btn} ${disabled ? styles.disabled : styles.active}`}
+     className={cx(styles.btn, disabled ? styles.disabled : styles.active)}
      onClick={onClick}
    >
      {label}
    </button>
(略)

特定の条件を満たす時のみクラスを追加で付与する方法

「条件を満たす場合のみクラスを付与」は条件 ? 付与するクラス : ''という三項演算子で表現できます。
しかし、&&演算子(論理積演算子、論理結合)を利用すると条件 && 付与するクラスというシンプルな形で表現できます。

&&演算子による表示制御の詳細解説は【React】JSXにおけるコンポーネントの表示・非表示の制御方法まとめで紹介しています。

以下はbuttonタグにstyles.btnクラスと、Propsのdisabledtrueであれば追加でstyles.disabledクラスを適用する例です。

src/components/shared/Button.tsx

import React, { FC } from "react";
import styles from "./Button.module.css";

type Props = {
  label: string;
  onClick: () => void;
  disabled: boolean;
};

export const Button: FC<Props> = ({ label, onClick, disabled }) => {
  return (
    <button
      className={`${styles.btn} ${disabled && styles.disabled}`}
      // 以下と同義
      // className={`${styles.btn} ${disabled ? styles.disabled : ""}`}
      onClick={onClick}
      disabled={disabled}
    >
      {label}
    </button>
  );
};

classnamesを使う場合は以下のようになります。

src/components/shared/Button.tsx

import React, { FC } from "react";
import styles from "./Button.module.css";
+ import cx from "classnames";
(略)
    <button
-     className={`${styles.btn} ${disabled && styles.disabled}`}
+     className={cx(styles.btn, disabled && styles.disabled)}
      onClick={onClick}
    >
      {label}
    </button>
(略)

さいごに

Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!