AstroJavaScript

ReactコンポーネントをAstroコンポーネントに書き換える際の、クラス名の取り扱いについて

すでにCreate React AppやVite、Next.jsなどでReactアプリとして構築しているものを、Astroにマイグレーションさせてみています。 その中で、「動的なクラス名の設定方法」が大きく異なる様子でし […]

広告ここから
広告ここまで

すでにCreate React AppやVite、Next.jsなどでReactアプリとして構築しているものを、Astroにマイグレーションさせてみています。

その中で、「動的なクラス名の設定方法」が大きく異なる様子でしたので、簡単に紹介します。

Reactではライブラリを利用して動的にクラス名を設定する

Reactでは、classnamesclsxなどのライブラリを使って動的にクラス名を設定します。

import clsx from 'clsx'

<div  className={clsx('relative px-4 sm:px-8 lg:px-12', props.className)} >

Astroでは、テンプレートディレクティブを利用する

一方Astroでは、class:listディレクティブを使うことで、動的にクラス名が設定できます。

<div class:list={['relative px-4 sm:px-8 lg:px-12', Astro.props.class]}>

clsxなどを使うこともできますが、せっかくなのでclass:listに変更して依存ライブラリを減らしましょう。

Before / After

簡単なBefore / Afterを用意してみました。

親コンポーネントからクラス名を追加で設定できるコンポーネントを想定しています。

import clsx from 'clsx'

function OuterContainer({ className, children, ...props }) {
  return (
    <div className={clsx('sm:px-8', className)} {...props}>
      <div className="mx-auto max-w-7xl lg:px-8">{children}</div>
    </div>
  )
}

Astroでは次のように実装します。

---

const {class: className, ...props } = Astro.props
---

<div class:list={['sm:px-8', className]} {...props}>
    <div class="mx-auto max-w-7xl lg:px-8"><slot></slot></div>
</div>

変更点としては、

  • clsxがなくなった
  • classNameclassに変わった
  • childrenから<slot></slot>に変わった

があります。

classの取り扱いに注意

一つハマったのが、{...props}class:listを利用するケースです。

<div class:list={['hello-world', Astro.props.class]} {...Astro.props}></div>

この要素を、<Component class="bye"></Component>のように使った場合、...Astro.props側で渡されたclassが勝ちます。

<div class='bye'></div>

...propsする場合は、class以外の値を渡すようにしましょう。

---
const {class: className, ...props } = Astro.props
---
<div class:list={['hello-world', class]} {...props}></div>

参考資料

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts