JSXでクラス名を動的に設定する
React で JSX を使用する場合、className 属性に文字列とプロパティを組み合わせたクラス名を動的に設定することができます。これは、コンポーネントのレンダリング時にクラス名をカスタマイズするのに便利です。
基本的な構文
<div className={`base-class ${propName}`}>
{/* コンテンツ */}
</div>
解説
-
テンプレートリテラル
className={
base-class ${propName}}
の部分は、テンプレートリテラルを使用しています。- テンプレートリテラルは、文字列の中に JavaScript の式を埋め込むことができる特別な構文です。
${propName}
の部分は、propName
というプロパティの値を文字列として埋め込みます。
-
クラス名の結合
base-class ${propName}
のように、スペースで区切ることで複数のクラス名を結合できます。base-class
は静的なクラス名で、常に適用されます。propName
の値は動的に変化するクラス名の一部となります。
例
function MyComponent(props) {
return (
<div className={`my-component ${props.extraClass}`}>
{/* コンテンツ */}
</div>
);
}
この例では、MyComponent
コンポーネントは extraClass
というプロパティを受け取ります。このプロパティの値は、my-component
という基本クラス名に追加され、最終的なクラス名として設定されます。
注意
- クラス名に特殊文字や空白が含まれる場合は、適切なエスケープ処理が必要になることがあります。
- プロパティの値が不定な場合は、適切なバリデーションやデフォルト値を設定することを推奨します。
テンプレートリテラルとクラス名の結合
<div className={`base-class ${propName}`}>
{/* コンテンツ */}
</div>
- スペースで区切る
複数のクラス名を結合する際に使用します。
function MyComponent(props) {
return (
<div className={`my-component ${props.extraClass}`}>
{/* コンテンツ */}
</div>
);
}
この例では、MyComponent
コンポーネントに渡される props.extraClass
の値に応じて、div
要素のクラス名が動的に変化します。例えば、props.extraClass
が 'is-active'
の場合、最終的なクラス名は 'my-component is-active'
となります。
具体的な使用例
条件に応じたクラス名の変更
function Button(props) {
const className = props.isActive ? 'button is-active' : 'button';
return (
<button className={className}>
{props.children}
</button>
);
}
- 三項演算子を使って条件分岐を行い、クラス名を動的に設定しています。
props.isActive
がtrue
の場合、'is-active'
というクラスが追加されます。
配列からクラス名を作成
function MyComponent(props) {
const classNames = ['base-class'];
if (props.isLarge) classNames.push('is-large');
if (props.isCentered) classNames.push('is-centered');
return (
<div className={classNames.join(' ')}>
{/* コンテンツ */}
</div>
);
}
- 複数の条件に基づいて、柔軟にクラス名を組み合わせることができます。
classNames
配列にクラス名を追加し、最後にjoin(' ')
で一つの文字列に結合します。
JSX で className を動的に設定する方法は、React コンポーネントの見た目を柔軟に制御する上で非常に重要です。テンプレートリテラルや条件分岐をうまく活用することで、様々なケースに対応することができます。
ポイント
- 配列を使って、複数のクラス名を管理できます。
- 条件分岐を使って、状況に応じて異なるクラス名を設定できます。
- クラス名はスペースで区切って結合できます。
- CSS モジュール
大規模なプロジェクトでは、CSS モジュールを利用することで、クラス名の衝突を防ぎ、スタイルを管理しやすくなります。 - style 属性
JSX では、style
属性を使用してインラインスタイルを指定することもできます。
JSX でクラス名を動的に設定する代替方法
CSS モジュール
- 方法
- CSS ファイルでクラス名を定義し、JavaScript ファイルからインポートして使用する
- JSX でインポートしたクラス名を直接
className
属性に指定
- メリット
- グローバルな名前空間の衝突を回避
- クラス名が分かりやすく、保守性が高い
- CSS-in-JS ソリューションとの連携も可能
// styles.module.css
.myButton {
/* ボタンのスタイル */
}
.isActive {
/* アクティブ状態のスタイル */
}
// MyComponent.jsx
import styles from './styles.module.css';
function MyComponent(props) {
return (
<button className={`${styles.myButton} ${props.isActive ? styles.isActive : ''}`}>
{/* ボタンのコンテンツ */}
</button>
);
}
CSS-in-JS
- 方法
- ライブラリが提供する関数を使ってスタイルを定義
- JSX で定義したスタイルを
className
属性に指定
- 代表的なライブラリ
- styled-components
- Emotion
- メリット
- JavaScript のオブジェクトでスタイルを定義
- 動的なスタイルの変更が容易
- コンポーネントレベルでスタイルをカプセル化
import styled from 'styled-components';
const Button = styled.button`
/* ボタンのベーススタイル */
${props => props.isActive && `
/* アクティブ状態のスタイル */
`}
`;
function MyComponent(props) {
return <Button isActive={props.isActive}>{/* ボタンのコンテンツ */}</Button>;
}
条件演算子による直接的な設定
- 方法
- メリット
- シンプルで簡潔な書き方
- 小規模なプロジェクトや簡単な条件分岐に適している
<div className={condition ? 'class1' : 'class2'}>{/* コンテンツ */}</div>
クラス名配列の結合
- 方法
- メリット
const classNames = ['base-class'];
if (props.isActive) classNames.push('is-active');
<div className={classNames.join(' ')}>{/* コンテンツ */}</div>
どの方法を選ぶべきか?
- チームの慣習
チームで共通のスタイル管理方法を定めておくことが重要 - スタイルの管理
グローバルなスタイル管理にはCSSモジュール、動的なスタイル変更にはCSS-in-JSが適している - プロジェクトの規模
小規模であれば条件演算子やクラス名配列で十分、大規模であればCSSモジュールやCSS-in-JSがおすすめ
JSX でクラス名を動的に設定する方法は、プロジェクトの規模や要件によって最適な方法が異なります。それぞれのメリットデメリットを理解し、適切な方法を選択しましょう。
- CSS プリプロセッサ
Sass や Less などの CSS プリプロセッサを使用することで、CSS の記述を効率化できます。 - style 属性
インラインスタイルを直接指定することもできますが、大規模なプロジェクトでは保守性が低下する可能性があります。
reactjs